]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 5 Dec 2021 13:54:21 +0000 (14:54 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 5 Dec 2021 13:54:21 +0000 (14:54 +0100)
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
drm-vc4-kms-add-missing-drm_crtc_commit_put.patch
drm-vc4-kms-clear-the-hvs-fifo-commit-pointer-once-done.patch
drm-vc4-kms-don-t-duplicate-pending-commit.patch
drm-vc4-kms-fix-previous-hvs-commit-wait.patch
drm-vc4-kms-fix-return-code-check.patch
drm-vc4-kms-wait-for-the-commit-before-increasing-our-clock-rate.patch
ipv4-convert-fib_num_tclassid_users-to-atomic_t.patch
iwlwifi-fix-warnings-produced-by-kernel-debug-options.patch
mt76-mt7915-fix-null-pointer-dereference-in-mt7915_get_phy_mode.patch
net-annotate-data-races-on-txq-xmit_lock_owner.patch
net-dsa-b53-add-spi-id-table.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-mlx5e-ipsec-fix-software-parser-inner-l3-type-setting-in-case-of-encapsulation.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-stmmac-avoid-dma_chan_control-write-if-no-split-header-support.patch
net-usb-lan78xx-lan78xx_phy_init-use-phy_poll-instead-of-0-if-no-irq-is-available.patch
octeontx2-af-fix-a-memleak-bug-in-rvu_mbox_init.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

38 files changed:
queue-5.15/alsa-intel-dsp-config-add-quirk-for-cml-devices-based-on-es8336-codec.patch [new file with mode: 0644]
queue-5.15/arm64-ftrace-add-missing-btis.patch [new file with mode: 0644]
queue-5.15/asoc-tegra-fix-kcontrol-put-callback-in-admaif.patch [new file with mode: 0644]
queue-5.15/asoc-tegra-fix-kcontrol-put-callback-in-ahub.patch [new file with mode: 0644]
queue-5.15/asoc-tegra-fix-kcontrol-put-callback-in-dmic.patch [new file with mode: 0644]
queue-5.15/asoc-tegra-fix-kcontrol-put-callback-in-dspk.patch [new file with mode: 0644]
queue-5.15/asoc-tegra-fix-kcontrol-put-callback-in-i2s.patch [new file with mode: 0644]
queue-5.15/asoc-tegra-fix-wrong-value-type-in-admaif.patch [new file with mode: 0644]
queue-5.15/asoc-tegra-fix-wrong-value-type-in-dmic.patch [new file with mode: 0644]
queue-5.15/asoc-tegra-fix-wrong-value-type-in-dspk.patch [new file with mode: 0644]
queue-5.15/asoc-tegra-fix-wrong-value-type-in-i2s.patch [new file with mode: 0644]
queue-5.15/dpaa2-eth-destroy-workqueue-at-the-end-of-remove-function.patch [new file with mode: 0644]
queue-5.15/drm-msm-a6xx-allocate-enough-space-for-gmu-registers.patch [new file with mode: 0644]
queue-5.15/drm-msm-do-hw_init-before-capturing-gpu-state.patch [new file with mode: 0644]
queue-5.15/drm-vc4-kms-add-missing-drm_crtc_commit_put.patch [new file with mode: 0644]
queue-5.15/drm-vc4-kms-clear-the-hvs-fifo-commit-pointer-once-done.patch [new file with mode: 0644]
queue-5.15/drm-vc4-kms-don-t-duplicate-pending-commit.patch [new file with mode: 0644]
queue-5.15/drm-vc4-kms-fix-previous-hvs-commit-wait.patch [new file with mode: 0644]
queue-5.15/drm-vc4-kms-fix-return-code-check.patch [new file with mode: 0644]
queue-5.15/drm-vc4-kms-wait-for-the-commit-before-increasing-our-clock-rate.patch [new file with mode: 0644]
queue-5.15/ipv4-convert-fib_num_tclassid_users-to-atomic_t.patch [new file with mode: 0644]
queue-5.15/iwlwifi-fix-warnings-produced-by-kernel-debug-options.patch [new file with mode: 0644]
queue-5.15/mt76-mt7915-fix-null-pointer-dereference-in-mt7915_get_phy_mode.patch [new file with mode: 0644]
queue-5.15/net-annotate-data-races-on-txq-xmit_lock_owner.patch [new file with mode: 0644]
queue-5.15/net-dsa-b53-add-spi-id-table.patch [new file with mode: 0644]
queue-5.15/net-marvell-mvpp2-fix-the-computation-of-shared-cpus.patch [new file with mode: 0644]
queue-5.15/net-mlx4_en-fix-an-use-after-free-bug-in-mlx4_en_try_alloc_resources.patch [new file with mode: 0644]
queue-5.15/net-mlx5e-ipsec-fix-software-parser-inner-l3-type-setting-in-case-of-encapsulation.patch [new file with mode: 0644]
queue-5.15/net-rds-correct-socket-tunable-error-in-rds_tcp_tune.patch [new file with mode: 0644]
queue-5.15/net-smc-fix-wrong-list_del-in-smc_lgr_cleanup_early.patch [new file with mode: 0644]
queue-5.15/net-smc-keep-smc_close_final-rc-during-active-close.patch [new file with mode: 0644]
queue-5.15/net-stmmac-avoid-dma_chan_control-write-if-no-split-header-support.patch [new file with mode: 0644]
queue-5.15/net-usb-lan78xx-lan78xx_phy_init-use-phy_poll-instead-of-0-if-no-irq-is-available.patch [new file with mode: 0644]
queue-5.15/octeontx2-af-fix-a-memleak-bug-in-rvu_mbox_init.patch [new file with mode: 0644]
queue-5.15/rxrpc-fix-rxrpc_local-leak-in-rxrpc_lookup_peer.patch [new file with mode: 0644]
queue-5.15/rxrpc-fix-rxrpc_peer-leak-in-rxrpc_look_up_bundle.patch [new file with mode: 0644]
queue-5.15/selftests-net-correct-case-name.patch [new file with mode: 0644]
queue-5.15/series

diff --git a/queue-5.15/alsa-intel-dsp-config-add-quirk-for-cml-devices-based-on-es8336-codec.patch b/queue-5.15/alsa-intel-dsp-config-add-quirk-for-cml-devices-based-on-es8336-codec.patch
new file mode 100644 (file)
index 0000000..0544dd7
--- /dev/null
@@ -0,0 +1,48 @@
+From ae26c08e6c8071ba8febb0c7c0829da96c75248c Mon Sep 17 00:00:00 2001
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+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 <pierre-louis.bossart@linux.intel.com>
+
+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 <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20211122232254.23362-1-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -252,6 +252,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,
+@@ -276,6 +281,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.15/arm64-ftrace-add-missing-btis.patch b/queue-5.15/arm64-ftrace-add-missing-btis.patch
new file mode 100644 (file)
index 0000000..7c09914
--- /dev/null
@@ -0,0 +1,116 @@
+From 35b6b28e69985eafb20b3b2c7bd6eca452b56b53 Mon Sep 17 00:00:00 2001
+From: Mark Rutland <mark.rutland@arm.com>
+Date: Mon, 29 Nov 2021 13:57:09 +0000
+Subject: arm64: ftrace: add missing BTIs
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+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 <mark.rutland@arm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Mark Brown <broonie@kernel.org>
+Cc: Will Deacon <will@kernel.org>
+Reviewed-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20211129135709.2274019-1-mark.rutland@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.15/asoc-tegra-fix-kcontrol-put-callback-in-admaif.patch b/queue-5.15/asoc-tegra-fix-kcontrol-put-callback-in-admaif.patch
new file mode 100644 (file)
index 0000000..7c7c5b1
--- /dev/null
@@ -0,0 +1,202 @@
+From e2b87a18a60c02d0dcd1de801d669587e516cc4d Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 18 Nov 2021 12:37:02 +0530
+Subject: ASoC: tegra: Fix kcontrol put callback in ADMAIF
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+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 <perex@perex.cz>
+Suggested-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/1637219231-406-8-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.15/asoc-tegra-fix-kcontrol-put-callback-in-ahub.patch b/queue-5.15/asoc-tegra-fix-kcontrol-put-callback-in-ahub.patch
new file mode 100644 (file)
index 0000000..5a3d465
--- /dev/null
@@ -0,0 +1,55 @@
+From a4e37950c9e9b126f9cbee79b8ab94a94646dcf1 Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 18 Nov 2021 12:37:06 +0530
+Subject: ASoC: tegra: Fix kcontrol put callback in AHUB
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+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 <spujar@nvidia.com>
+Suggested-by: Jaroslav Kysela <perex@perex.cz>
+Suggested-by: Mark Brown <broonie@kernel.org>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/1637219231-406-12-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.15/asoc-tegra-fix-kcontrol-put-callback-in-dmic.patch b/queue-5.15/asoc-tegra-fix-kcontrol-put-callback-in-dmic.patch
new file mode 100644 (file)
index 0000000..118f813
--- /dev/null
@@ -0,0 +1,248 @@
+From a347dfa10262fa0a10e2b1970ea0194e3d4a3251 Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 18 Nov 2021 12:37:04 +0530
+Subject: ASoC: tegra: Fix kcontrol put callback in DMIC
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+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 <perex@perex.cz>
+Suggested-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/1637219231-406-10-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.15/asoc-tegra-fix-kcontrol-put-callback-in-dspk.patch b/queue-5.15/asoc-tegra-fix-kcontrol-put-callback-in-dspk.patch
new file mode 100644 (file)
index 0000000..8b4fafc
--- /dev/null
@@ -0,0 +1,243 @@
+From d6202a57e79d102271d38c34481fedc9d4c79694 Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 18 Nov 2021 12:37:05 +0530
+Subject: ASoC: tegra: Fix kcontrol put callback in DSPK
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+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 <perex@perex.cz>
+Suggested-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/1637219231-406-11-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.15/asoc-tegra-fix-kcontrol-put-callback-in-i2s.patch b/queue-5.15/asoc-tegra-fix-kcontrol-put-callback-in-i2s.patch
new file mode 100644 (file)
index 0000000..486b027
--- /dev/null
@@ -0,0 +1,379 @@
+From f21a9df3f7cb0005947679d7b9237c90574e229a Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 18 Nov 2021 12:37:03 +0530
+Subject: ASoC: tegra: Fix kcontrol put callback in I2S
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+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 <perex@perex.cz>
+Suggested-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/1637219231-406-9-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.15/asoc-tegra-fix-wrong-value-type-in-admaif.patch b/queue-5.15/asoc-tegra-fix-wrong-value-type-in-admaif.patch
new file mode 100644 (file)
index 0000000..0e991db
--- /dev/null
@@ -0,0 +1,43 @@
+From 884c6cb3b7030f75c46e55b9e625d2372708c306 Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 18 Nov 2021 12:36:56 +0530
+Subject: ASoC: tegra: Fix wrong value type in ADMAIF
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+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 <tiwai@suse.de>
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/1637219231-406-2-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.15/asoc-tegra-fix-wrong-value-type-in-dmic.patch b/queue-5.15/asoc-tegra-fix-wrong-value-type-in-dmic.patch
new file mode 100644 (file)
index 0000000..73e8ae0
--- /dev/null
@@ -0,0 +1,73 @@
+From 559d234569a998a4004de1bd1f12da5487fb826e Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 18 Nov 2021 12:36:58 +0530
+Subject: ASoC: tegra: Fix wrong value type in DMIC
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+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 <tiwai@suse.de>
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/1637219231-406-4-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.15/asoc-tegra-fix-wrong-value-type-in-dspk.patch b/queue-5.15/asoc-tegra-fix-wrong-value-type-in-dspk.patch
new file mode 100644 (file)
index 0000000..c1bab5e
--- /dev/null
@@ -0,0 +1,73 @@
+From 3aa0d5c8bb3f5ef622ec2764823f551a1f630711 Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 18 Nov 2021 12:36:59 +0530
+Subject: ASoC: tegra: Fix wrong value type in DSPK
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+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 <tiwai@suse.de>
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/1637219231-406-5-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.15/asoc-tegra-fix-wrong-value-type-in-i2s.patch b/queue-5.15/asoc-tegra-fix-wrong-value-type-in-i2s.patch
new file mode 100644 (file)
index 0000000..b457a85
--- /dev/null
@@ -0,0 +1,110 @@
+From 8a2c2fa0c5331445c801e9241f2bb4e0e2a895a8 Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 18 Nov 2021 12:36:57 +0530
+Subject: ASoC: tegra: Fix wrong value type in I2S
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+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 <tiwai@suse.de>
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Reviewed-by: Takashi Iwai <tiwai@suse.de>
+Link: https://lore.kernel.org/r/1637219231-406-3-git-send-email-spujar@nvidia.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.15/dpaa2-eth-destroy-workqueue-at-the-end-of-remove-function.patch b/queue-5.15/dpaa2-eth-destroy-workqueue-at-the-end-of-remove-function.patch
new file mode 100644 (file)
index 0000000..a619fb0
--- /dev/null
@@ -0,0 +1,35 @@
+From f4a8adbfe4841491b60c14fe610571e1422359f9 Mon Sep 17 00:00:00 2001
+From: Dongliang Mu <mudongliangabcd@gmail.com>
+Date: Tue, 30 Nov 2021 12:05:54 +0800
+Subject: dpaa2-eth: destroy workqueue at the end of remove function
+
+From: Dongliang Mu <mudongliangabcd@gmail.com>
+
+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 <mudongliangabcd@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -4538,6 +4538,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.15/drm-msm-a6xx-allocate-enough-space-for-gmu-registers.patch b/queue-5.15/drm-msm-a6xx-allocate-enough-space-for-gmu-registers.patch
new file mode 100644 (file)
index 0000000..ef05a34
--- /dev/null
@@ -0,0 +1,72 @@
+From b4d25abf9720b69a03465b09d0d62d1998ed6708 Mon Sep 17 00:00:00 2001
+From: Douglas Anderson <dianders@chromium.org>
+Date: Wed, 3 Nov 2021 15:31:08 -0700
+Subject: drm/msm/a6xx: Allocate enough space for GMU registers
+
+From: Douglas Anderson <dianders@chromium.org>
+
+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 <dianders@chromium.org>
+Link: https://lore.kernel.org/r/20211103153049.1.Idfa574ccb529d17b69db3a1852e49b580132035c@changeid
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.15/drm-msm-do-hw_init-before-capturing-gpu-state.patch b/queue-5.15/drm-msm-do-hw_init-before-capturing-gpu-state.patch
new file mode 100644 (file)
index 0000000..1fdbe03
--- /dev/null
@@ -0,0 +1,35 @@
+From e4840d537c2c6b1189d4de16ee0f4820e069dcea Mon Sep 17 00:00:00 2001
+From: Rob Clark <robdclark@chromium.org>
+Date: Mon, 8 Nov 2021 10:01:22 -0800
+Subject: drm/msm: Do hw_init() before capturing GPU state
+
+From: Rob Clark <robdclark@chromium.org>
+
+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 <robdclark@chromium.org>
+Link: https://lore.kernel.org/r/20211108180122.487859-1-robdclark@gmail.com
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.15/drm-vc4-kms-add-missing-drm_crtc_commit_put.patch b/queue-5.15/drm-vc4-kms-add-missing-drm_crtc_commit_put.patch
new file mode 100644 (file)
index 0000000..c9a4ec5
--- /dev/null
@@ -0,0 +1,54 @@
+From 049cfff8d53a30cae3349ff71a4c01b7d9981bc2 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Wed, 17 Nov 2021 10:45:24 +0100
+Subject: drm/vc4: kms: Add missing drm_crtc_commit_put
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+commit 049cfff8d53a30cae3349ff71a4c01b7d9981bc2 upstream.
+
+Commit 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a
+commit") introduced a global state for the HVS, with each FIFO storing
+the current CRTC commit so that we can properly synchronize commits.
+
+However, the refcounting was off and we thus ended up leaking the
+drm_crtc_commit structure every commit. Add a drm_crtc_commit_put to
+prevent the leakage.
+
+Fixes: 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a commit")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Tested-by: Jian-Hong Pan <jhp@endlessos.org>
+Link: https://lore.kernel.org/r/20211117094527.146275-4-maxime@cerno.tech
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/vc4/vc4_kms.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_kms.c
+@@ -361,6 +361,7 @@ static void vc4_atomic_commit_tail(struc
+               struct vc4_crtc_state *vc4_crtc_state =
+                       to_vc4_crtc_state(old_crtc_state);
+               unsigned int channel = vc4_crtc_state->assigned_channel;
++              struct drm_crtc_commit *commit;
+               int ret;
+               if (channel == VC4_HVS_CHANNEL_DISABLED)
+@@ -369,9 +370,15 @@ static void vc4_atomic_commit_tail(struc
+               if (!old_hvs_state->fifo_state[channel].in_use)
+                       continue;
+-              ret = drm_crtc_commit_wait(old_hvs_state->fifo_state[channel].pending_commit);
++              commit = old_hvs_state->fifo_state[channel].pending_commit;
++              if (!commit)
++                      continue;
++
++              ret = drm_crtc_commit_wait(commit);
+               if (ret)
+                       drm_err(dev, "Timed out waiting for commit\n");
++
++              drm_crtc_commit_put(commit);
+       }
+       if (vc4->hvs->hvs5)
diff --git a/queue-5.15/drm-vc4-kms-clear-the-hvs-fifo-commit-pointer-once-done.patch b/queue-5.15/drm-vc4-kms-clear-the-hvs-fifo-commit-pointer-once-done.patch
new file mode 100644 (file)
index 0000000..b6b61c0
--- /dev/null
@@ -0,0 +1,42 @@
+From d134c5ff71c7f2320fc7997f2fbbdedf0c76889a Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Wed, 17 Nov 2021 10:45:25 +0100
+Subject: drm/vc4: kms: Clear the HVS FIFO commit pointer once done
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+commit d134c5ff71c7f2320fc7997f2fbbdedf0c76889a upstream.
+
+Commit 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a
+commit") introduced a wait on the previous commit done on a given HVS
+FIFO.
+
+However, we never cleared that pointer once done. Since
+drm_crtc_commit_put can free the drm_crtc_commit structure directly if
+we were the last user, this means that it can lead to a use-after free
+if we were to duplicate the state, and that stale pointer would even be
+copied to the new state.
+
+Set the pointer to NULL once we're done with the wait so that we don't
+carry over a pointer to a free'd structure.
+
+Fixes: 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a commit")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Tested-by: Jian-Hong Pan <jhp@endlessos.org>
+Link: https://lore.kernel.org/r/20211117094527.146275-5-maxime@cerno.tech
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/vc4/vc4_kms.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/gpu/drm/vc4/vc4_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_kms.c
+@@ -379,6 +379,7 @@ static void vc4_atomic_commit_tail(struc
+                       drm_err(dev, "Timed out waiting for commit\n");
+               drm_crtc_commit_put(commit);
++              old_hvs_state->fifo_state[channel].pending_commit = NULL;
+       }
+       if (vc4->hvs->hvs5)
diff --git a/queue-5.15/drm-vc4-kms-don-t-duplicate-pending-commit.patch b/queue-5.15/drm-vc4-kms-don-t-duplicate-pending-commit.patch
new file mode 100644 (file)
index 0000000..b1d7b31
--- /dev/null
@@ -0,0 +1,45 @@
+From d354699e2292c60f25496d3c31ce4e7b1563b899 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Wed, 17 Nov 2021 10:45:26 +0100
+Subject: drm/vc4: kms: Don't duplicate pending commit
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+commit d354699e2292c60f25496d3c31ce4e7b1563b899 upstream.
+
+Our HVS global state, when duplicated, will also copy the pointer to the
+drm_crtc_commit (and increase the reference count) for each FIFO if the
+pointer is not NULL.
+
+However, our atomic_setup function will overwrite that pointer without
+putting the reference back leading to a memory leak.
+
+Since the commit is only relevant during the atomic commit process, it
+doesn't make sense to duplicate the reference to the commit anyway.
+Let's remove it.
+
+Fixes: 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a commit")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Tested-by: Jian-Hong Pan <jhp@endlessos.org>
+Link: https://lore.kernel.org/r/20211117094527.146275-6-maxime@cerno.tech
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/vc4/vc4_kms.c |    6 ------
+ 1 file changed, 6 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_kms.c
+@@ -676,12 +676,6 @@ vc4_hvs_channels_duplicate_state(struct
+       for (i = 0; i < HVS_NUM_CHANNELS; i++) {
+               state->fifo_state[i].in_use = old_state->fifo_state[i].in_use;
+-
+-              if (!old_state->fifo_state[i].pending_commit)
+-                      continue;
+-
+-              state->fifo_state[i].pending_commit =
+-                      drm_crtc_commit_get(old_state->fifo_state[i].pending_commit);
+       }
+       return &state->base;
diff --git a/queue-5.15/drm-vc4-kms-fix-previous-hvs-commit-wait.patch b/queue-5.15/drm-vc4-kms-fix-previous-hvs-commit-wait.patch
new file mode 100644 (file)
index 0000000..f19890a
--- /dev/null
@@ -0,0 +1,90 @@
+From 6052a3110be208e547a4a8aeb184446199a16e8a Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Wed, 17 Nov 2021 10:45:27 +0100
+Subject: drm/vc4: kms: Fix previous HVS commit wait
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+commit 6052a3110be208e547a4a8aeb184446199a16e8a upstream.
+
+Our current code is supposed to serialise the commits by waiting for all
+the drm_crtc_commits associated to the previous HVS state.
+
+However, assuming we have two CRTCs running and being configured and we
+configure each one alternately, we end up in a situation where we're
+not waiting at all.
+
+Indeed, starting with a state (state 0) where both CRTCs are running,
+and doing a commit (state 1) on the first CRTC (CRTC 0), we'll associate
+its commit to its assigned FIFO in vc4_hvs_state.
+
+If we get a new commit (state 2), this time affecting the second CRTC
+(CRTC 1), the DRM core will allow both commits to execute in parallel
+(assuming they don't have any share resources).
+
+Our code in vc4_atomic_commit_tail is supposed to make sure we only get
+one commit at a time and serialised by order of submission. It does so
+by using for_each_old_crtc_in_state, making sure that the CRTC has a
+FIFO assigned, is used, and has a commit pending. If it does, then we'll
+wait for the commit before going forward.
+
+During the transition from state 0 to state 1, as our old CRTC state we
+get the CRTC 0 state 0, its commit, we wait for it, everything works fine.
+
+During the transition from state 1 to state 2 though, the use of
+for_each_old_crtc_in_state is wrong. Indeed, while the code assumes it's
+returning the state of the CRTC in the old state (so CRTC 0 state 1), it
+actually returns the old state of the CRTC affected by the current
+commit, so CRTC 0 state 0 since it wasn't part of state 1.
+
+Due to this, if we alternate between the configuration of CRTC 0 and
+CRTC 1, we never actually wait for anything since we should be waiting
+on the other every time, but it never is affected by the previous
+commit.
+
+Change the logic to, at every commit, look at every FIFO in the previous
+HVS state, and if it's in use and has a commit associated to it, wait
+for that commit.
+
+Fixes: 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a commit")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Tested-by: Jian-Hong Pan <jhp@endlessos.org>
+Link: https://lore.kernel.org/r/20211117094527.146275-7-maxime@cerno.tech
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/vc4/vc4_kms.c |   10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_kms.c
+@@ -337,10 +337,10 @@ static void vc4_atomic_commit_tail(struc
+       struct drm_device *dev = state->dev;
+       struct vc4_dev *vc4 = to_vc4_dev(dev);
+       struct vc4_hvs *hvs = vc4->hvs;
+-      struct drm_crtc_state *old_crtc_state;
+       struct drm_crtc_state *new_crtc_state;
+       struct drm_crtc *crtc;
+       struct vc4_hvs_state *old_hvs_state;
++      unsigned int channel;
+       int i;
+       for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
+@@ -357,16 +357,10 @@ static void vc4_atomic_commit_tail(struc
+       if (IS_ERR(old_hvs_state))
+               return;
+-      for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
+-              struct vc4_crtc_state *vc4_crtc_state =
+-                      to_vc4_crtc_state(old_crtc_state);
+-              unsigned int channel = vc4_crtc_state->assigned_channel;
++      for (channel = 0; channel < HVS_NUM_CHANNELS; channel++) {
+               struct drm_crtc_commit *commit;
+               int ret;
+-              if (channel == VC4_HVS_CHANNEL_DISABLED)
+-                      continue;
+-
+               if (!old_hvs_state->fifo_state[channel].in_use)
+                       continue;
diff --git a/queue-5.15/drm-vc4-kms-fix-return-code-check.patch b/queue-5.15/drm-vc4-kms-fix-return-code-check.patch
new file mode 100644 (file)
index 0000000..1972f6d
--- /dev/null
@@ -0,0 +1,56 @@
+From f927767978d201d4ac023fcd797adbb963a6565d Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Wed, 17 Nov 2021 10:45:23 +0100
+Subject: drm/vc4: kms: Fix return code check
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+commit f927767978d201d4ac023fcd797adbb963a6565d upstream.
+
+The HVS global state functions return an error pointer, but in most
+cases we check if it's NULL, possibly resulting in an invalid pointer
+dereference.
+
+Fixes: 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a commit")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Tested-by: Jian-Hong Pan <jhp@endlessos.org>
+Link: https://lore.kernel.org/r/20211117094527.146275-3-maxime@cerno.tech
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/vc4/vc4_kms.c |   10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_kms.c
+@@ -354,7 +354,7 @@ static void vc4_atomic_commit_tail(struc
+       }
+       old_hvs_state = vc4_hvs_get_old_global_state(state);
+-      if (!old_hvs_state)
++      if (IS_ERR(old_hvs_state))
+               return;
+       for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
+@@ -410,8 +410,8 @@ static int vc4_atomic_commit_setup(struc
+       unsigned int i;
+       hvs_state = vc4_hvs_get_new_global_state(state);
+-      if (!hvs_state)
+-              return -EINVAL;
++      if (WARN_ON(IS_ERR(hvs_state)))
++              return PTR_ERR(hvs_state);
+       for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
+               struct vc4_crtc_state *vc4_crtc_state =
+@@ -762,8 +762,8 @@ static int vc4_pv_muxing_atomic_check(st
+       unsigned int i;
+       hvs_new_state = vc4_hvs_get_global_state(state);
+-      if (!hvs_new_state)
+-              return -EINVAL;
++      if (IS_ERR(hvs_new_state))
++              return PTR_ERR(hvs_new_state);
+       for (i = 0; i < ARRAY_SIZE(hvs_new_state->fifo_state); i++)
+               if (!hvs_new_state->fifo_state[i].in_use)
diff --git a/queue-5.15/drm-vc4-kms-wait-for-the-commit-before-increasing-our-clock-rate.patch b/queue-5.15/drm-vc4-kms-wait-for-the-commit-before-increasing-our-clock-rate.patch
new file mode 100644 (file)
index 0000000..11c656b
--- /dev/null
@@ -0,0 +1,62 @@
+From 0c980a006d3fbee86c4d0698f66d6f5381831787 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Wed, 17 Nov 2021 10:45:22 +0100
+Subject: drm/vc4: kms: Wait for the commit before increasing our clock rate
+
+From: Maxime Ripard <maxime@cerno.tech>
+
+commit 0c980a006d3fbee86c4d0698f66d6f5381831787 upstream.
+
+Several DRM/KMS atomic commits can run in parallel if they affect
+different CRTC. These commits share the global HVS state, so we have
+some code to make sure we run commits in sequence. This synchronization
+code is one of the first thing that runs in vc4_atomic_commit_tail().
+
+Another constraints we have is that we need to make sure the HVS clock
+gets a boost during the commit. That code relies on clk_set_min_rate and
+will remove the old minimum and set a new one. We also need another,
+temporary, minimum for the duration of the commit.
+
+The algorithm is thus to set a temporary minimum, drop the previous
+one, do the commit, and finally set the minimum for the current mode.
+
+However, the part that sets the temporary minimum and drops the older
+one runs before the commit synchronization code.
+
+Thus, under the proper conditions, we can end up mixing up the minimums
+and ending up with the wrong one for our current step.
+
+To avoid it, let's move the clock setup in the protected section.
+
+Fixes: d7d96c00e585 ("drm/vc4: hvs: Boost the core clock during modeset")
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Tested-by: Jian-Hong Pan <jhp@endlessos.org>
+Link: https://lore.kernel.org/r/20211117094527.146275-2-maxime@cerno.tech
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/vc4/vc4_kms.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_kms.c
+@@ -353,9 +353,6 @@ static void vc4_atomic_commit_tail(struc
+               vc4_hvs_mask_underrun(dev, vc4_crtc_state->assigned_channel);
+       }
+-      if (vc4->hvs->hvs5)
+-              clk_set_min_rate(hvs->core_clk, 500000000);
+-
+       old_hvs_state = vc4_hvs_get_old_global_state(state);
+       if (!old_hvs_state)
+               return;
+@@ -377,6 +374,9 @@ static void vc4_atomic_commit_tail(struc
+                       drm_err(dev, "Timed out waiting for commit\n");
+       }
++      if (vc4->hvs->hvs5)
++              clk_set_min_rate(hvs->core_clk, 500000000);
++
+       drm_atomic_helper_commit_modeset_disables(dev, state);
+       vc4_ctm_commit(vc4, state);
diff --git a/queue-5.15/ipv4-convert-fib_num_tclassid_users-to-atomic_t.patch b/queue-5.15/ipv4-convert-fib_num_tclassid_users-to-atomic_t.patch
new file mode 100644 (file)
index 0000000..a0470dc
--- /dev/null
@@ -0,0 +1,102 @@
+From 213f5f8f31f10aa1e83187ae20fb7fa4e626b724 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 1 Dec 2021 18:26:35 -0800
+Subject: ipv4: convert fib_num_tclassid_users to atomic_t
+
+From: Eric Dumazet <edumazet@google.com>
+
+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 <edumazet@google.com>
+Cc: David Ahern <dsahern@kernel.org>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -438,7 +438,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
+@@ -65,7 +65,7 @@ struct netns_ipv4 {
+       bool                    fib_has_custom_local_routes;
+       bool                    fib_offload_disabled;
+ #ifdef CONFIG_IP_ROUTE_CLASSID
+-      int                     fib_num_tclassid_users;
++      atomic_t                fib_num_tclassid_users;
+ #endif
+       struct hlist_head       *fib_table_hash;
+       struct sock             *fibnl;
+--- a/net/ipv4/fib_frontend.c
++++ b/net/ipv4/fib_frontend.c
+@@ -1582,7 +1582,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
+@@ -220,7 +220,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);
+ }
+@@ -632,7 +632,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.15/iwlwifi-fix-warnings-produced-by-kernel-debug-options.patch b/queue-5.15/iwlwifi-fix-warnings-produced-by-kernel-debug-options.patch
new file mode 100644 (file)
index 0000000..dcc5450
--- /dev/null
@@ -0,0 +1,74 @@
+From f5cecf1d4c5ff76172928bc32e99ca56a5ca2f56 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C5=81ukasz=20Bartosik?= <lb@semihalf.com>
+Date: Wed, 10 Nov 2021 22:57:44 +0100
+Subject: iwlwifi: fix warnings produced by kernel debug options
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Łukasz Bartosik <lb@semihalf.com>
+
+commit f5cecf1d4c5ff76172928bc32e99ca56a5ca2f56 upstream.
+
+Fix warnings produced by:
+- lockdep_assert_wiphy() in function reg_process_self_managed_hint(),
+- wiphy_dereference() in function iwl_mvm_init_fw_regd().
+Both function are expected to be called in critical section.
+
+The warnings were discovered when running v5.15 kernel
+with debug options enabled:
+
+1)
+Hardware name: Google Delbin/Delbin
+RIP: 0010:reg_process_self_managed_hint+0x254/0x347 [cfg80211]
+...
+Call Trace:
+regulatory_set_wiphy_regd_sync+0x3d/0xb0
+iwl_mvm_init_mcc+0x49d/0x5a2
+iwl_op_mode_mvm_start+0x1b58/0x2507
+? iwl_mvm_reprobe_wk+0x94/0x94
+_iwl_op_mode_start+0x146/0x1a3
+iwl_opmode_register+0xda/0x13d
+init_module+0x28/0x1000
+
+2)
+drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c:263 suspicious rcu_dereference_protected() usage!
+...
+Hardware name: Google Delbin/Delbin, BIOS Google_Delbin
+Call Trace:
+dump_stack_lvl+0xb1/0xe6
+iwl_mvm_init_fw_regd+0x2e7/0x379
+iwl_mvm_init_mcc+0x2c6/0x5a2
+iwl_op_mode_mvm_start+0x1b58/0x2507
+? iwl_mvm_reprobe_wk+0x94/0x94
+_iwl_op_mode_start+0x146/0x1a3
+iwl_opmode_register+0xda/0x13d
+init_module+0x28/0x100
+
+Fixes: a05829a7222e ("cfg80211: avoid holding the RTNL when calling the driver")
+Signed-off-by: Łukasz Bartosik <lb@semihalf.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20211110215744.5487-1-lukasz.bartosik@semihalf.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/ops.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+@@ -687,6 +687,7 @@ static int iwl_mvm_start_get_nvm(struct
+       int ret;
+       rtnl_lock();
++      wiphy_lock(mvm->hw->wiphy);
+       mutex_lock(&mvm->mutex);
+       ret = iwl_run_init_mvm_ucode(mvm);
+@@ -702,6 +703,7 @@ static int iwl_mvm_start_get_nvm(struct
+               iwl_mvm_stop_device(mvm);
+       mutex_unlock(&mvm->mutex);
++      wiphy_unlock(mvm->hw->wiphy);
+       rtnl_unlock();
+       if (ret < 0)
diff --git a/queue-5.15/mt76-mt7915-fix-null-pointer-dereference-in-mt7915_get_phy_mode.patch b/queue-5.15/mt76-mt7915-fix-null-pointer-dereference-in-mt7915_get_phy_mode.patch
new file mode 100644 (file)
index 0000000..f8a9a1f
--- /dev/null
@@ -0,0 +1,93 @@
+From 6e53d6d26920d5221d3f4d4f5ffdd629ea69aa5c Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Thu, 18 Nov 2021 13:47:48 +0100
+Subject: mt76: mt7915: fix NULL pointer dereference in mt7915_get_phy_mode
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+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 <lorenzo@kernel.org>
+Acked-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/ddae419a740f1fb9e48afd432035e9f394f512ee.1637239456.git.lorenzo@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -176,7 +176,7 @@ mt7915_get_phy_mode(struct ieee80211_vif
+               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;
+@@ -187,7 +187,7 @@ mt7915_get_phy_mode(struct ieee80211_vif
+               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.15/net-annotate-data-races-on-txq-xmit_lock_owner.patch b/queue-5.15/net-annotate-data-races-on-txq-xmit_lock_owner.patch
new file mode 100644 (file)
index 0000000..563f3d4
--- /dev/null
@@ -0,0 +1,193 @@
+From 7a10d8c810cfad3e79372d7d1c77899d86cd6662 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Tue, 30 Nov 2021 09:01:55 -0800
+Subject: net: annotate data-races on txq->xmit_lock_owner
+
+From: Eric Dumazet <edumazet@google.com>
+
+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 <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Link: https://lore.kernel.org/r/20211130170155.2331929-1-eric.dumazet@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -4403,7 +4403,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)
+@@ -4420,26 +4421,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
+@@ -4195,7 +4195,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.15/net-dsa-b53-add-spi-id-table.patch b/queue-5.15/net-dsa-b53-add-spi-id-table.patch
new file mode 100644 (file)
index 0000000..6f0d9fe
--- /dev/null
@@ -0,0 +1,53 @@
+From 88362ebfd7fb569c78d5cb507aa9d3c8fc203839 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Wed, 1 Dec 2021 20:17:20 -0800
+Subject: net: dsa: b53: Add SPI ID table
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+commit 88362ebfd7fb569c78d5cb507aa9d3c8fc203839 upstream.
+
+Currently autoloading for SPI devices does not use the DT ID table, it
+uses SPI modalises. Supporting OF modalises is going to be difficult if
+not impractical, an attempt was made but has been reverted, so ensure
+that module autoloading works for this driver by adding an id_table
+listing the SPI IDs for everything.
+
+Fixes: 96c8395e2166 ("spi: Revert modalias changes")
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/dsa/b53/b53_spi.c |   14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_spi.c
++++ b/drivers/net/dsa/b53/b53_spi.c
+@@ -349,6 +349,19 @@ static const struct of_device_id b53_spi
+ };
+ MODULE_DEVICE_TABLE(of, b53_spi_of_match);
++static const struct spi_device_id b53_spi_ids[] = {
++      { .name = "bcm5325" },
++      { .name = "bcm5365" },
++      { .name = "bcm5395" },
++      { .name = "bcm5397" },
++      { .name = "bcm5398" },
++      { .name = "bcm53115" },
++      { .name = "bcm53125" },
++      { .name = "bcm53128" },
++      { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(spi, b53_spi_ids);
++
+ static struct spi_driver b53_spi_driver = {
+       .driver = {
+               .name   = "b53-switch",
+@@ -357,6 +370,7 @@ static struct spi_driver b53_spi_driver
+       .probe  = b53_spi_probe,
+       .remove = b53_spi_remove,
+       .shutdown = b53_spi_shutdown,
++      .id_table = b53_spi_ids,
+ };
+ module_spi_driver(b53_spi_driver);
diff --git a/queue-5.15/net-marvell-mvpp2-fix-the-computation-of-shared-cpus.patch b/queue-5.15/net-marvell-mvpp2-fix-the-computation-of-shared-cpus.patch
new file mode 100644 (file)
index 0000000..4808d34
--- /dev/null
@@ -0,0 +1,33 @@
+From b83f5ac7d922e69a109261f5f940eebbd4e514c4 Mon Sep 17 00:00:00 2001
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Date: Mon, 29 Nov 2021 22:53:27 +0100
+Subject: net: marvell: mvpp2: Fix the computation of shared CPUs
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+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 <christophe.jaillet@wanadoo.fr>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -7457,7 +7457,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.15/net-mlx4_en-fix-an-use-after-free-bug-in-mlx4_en_try_alloc_resources.patch b/queue-5.15/net-mlx4_en-fix-an-use-after-free-bug-in-mlx4_en_try_alloc_resources.patch
new file mode 100644 (file)
index 0000000..d03f464
--- /dev/null
@@ -0,0 +1,59 @@
+From addad7643142f500080417dd7272f49b7a185570 Mon Sep 17 00:00:00 2001
+From: Zhou Qingyang <zhou1615@umn.edu>
+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 <zhou1615@umn.edu>
+
+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 <zhou1615@umn.edu>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Link: https://lore.kernel.org/r/20211130164438.190591-1-zhou1615@umn.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -2286,9 +2286,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.15/net-mlx5e-ipsec-fix-software-parser-inner-l3-type-setting-in-case-of-encapsulation.patch b/queue-5.15/net-mlx5e-ipsec-fix-software-parser-inner-l3-type-setting-in-case-of-encapsulation.patch
new file mode 100644 (file)
index 0000000..341f917
--- /dev/null
@@ -0,0 +1,39 @@
+From c65d638ab39034cbaa36773b980d28106cfc81fa Mon Sep 17 00:00:00 2001
+From: Raed Salem <raeds@nvidia.com>
+Date: Wed, 17 Nov 2021 13:33:57 +0200
+Subject: net/mlx5e: IPsec: Fix Software parser inner l3 type setting in case of encapsulation
+
+From: Raed Salem <raeds@nvidia.com>
+
+commit c65d638ab39034cbaa36773b980d28106cfc81fa upstream.
+
+Current code wrongly uses the skb->protocol field which reflects the
+outer l3 protocol to set the inner l3 type in Software Parser (SWP)
+fields settings in the ethernet segment (eseg) in flows where inner
+l3 exists like in Vxlan over ESP flow, the above method wrongly use
+the outer protocol type instead of the inner one. thus breaking cases
+where inner and outer headers have different protocols.
+
+Fix by setting the inner l3 type in SWP according to the inner l3 ip
+header version.
+
+Fixes: 2ac9cfe78223 ("net/mlx5e: IPSec, Add Innova IPSec offload TX data path")
+Signed-off-by: Raed Salem <raeds@nvidia.com>
+Reviewed-by: Maor Dickman <maord@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c
+@@ -191,7 +191,7 @@ static void mlx5e_ipsec_set_swp(struct s
+                       eseg->swp_inner_l3_offset = skb_inner_network_offset(skb) / 2;
+                       eseg->swp_inner_l4_offset =
+                               (skb->csum_start + skb->head - skb->data) / 2;
+-                      if (skb->protocol == htons(ETH_P_IPV6))
++                      if (inner_ip_hdr(skb)->version == 6)
+                               eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L3_IPV6;
+                       break;
+               default:
diff --git a/queue-5.15/net-rds-correct-socket-tunable-error-in-rds_tcp_tune.patch b/queue-5.15/net-rds-correct-socket-tunable-error-in-rds_tcp_tune.patch
new file mode 100644 (file)
index 0000000..7d23aa3
--- /dev/null
@@ -0,0 +1,32 @@
+From 19f36edf14bcdb783aef3af8217df96f76a8ce34 Mon Sep 17 00:00:00 2001
+From: William Kucharski <william.kucharski@oracle.com>
+Date: Wed, 1 Dec 2021 07:45:22 -0700
+Subject: net/rds: correct socket tunable error in rds_tcp_tune()
+
+From: William Kucharski <william.kucharski@oracle.com>
+
+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 <william.kucharski@oracle.com>
+Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.15/net-smc-fix-wrong-list_del-in-smc_lgr_cleanup_early.patch b/queue-5.15/net-smc-fix-wrong-list_del-in-smc_lgr_cleanup_early.patch
new file mode 100644 (file)
index 0000000..3ab35ac
--- /dev/null
@@ -0,0 +1,89 @@
+From 789b6cc2a5f9123b9c549b886fdc47c865cfe0ba Mon Sep 17 00:00:00 2001
+From: Dust Li <dust.li@linux.alibaba.com>
+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 <dust.li@linux.alibaba.com>
+
+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 <dust.li@linux.alibaba.com>
+Acked-by: Karsten Graul <kgraul@linux.ibm.com>
+Reviewed-by: Tony Lu <tonylu@linux.alibaba.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -582,18 +582,17 @@ int smcd_nl_get_lgr(struct sk_buff *skb,
+ 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.15/net-smc-keep-smc_close_final-rc-during-active-close.patch b/queue-5.15/net-smc-keep-smc_close_final-rc-during-active-close.patch
new file mode 100644 (file)
index 0000000..83daeeb
--- /dev/null
@@ -0,0 +1,53 @@
+From 00e158fb91dfaff3f94746f260d11f1a4853506e Mon Sep 17 00:00:00 2001
+From: Tony Lu <tonylu@linux.alibaba.com>
+Date: Wed, 1 Dec 2021 14:42:16 +0800
+Subject: net/smc: Keep smc_close_final rc during active close
+
+From: Tony Lu <tonylu@linux.alibaba.com>
+
+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 <kgraul@linux.ibm.com>
+Signed-off-by: Tony Lu <tonylu@linux.alibaba.com>
+Reviewed-by: Wen Gu <guwen@linux.alibaba.com>
+Acked-by: Karsten Graul <kgraul@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.15/net-stmmac-avoid-dma_chan_control-write-if-no-split-header-support.patch b/queue-5.15/net-stmmac-avoid-dma_chan_control-write-if-no-split-header-support.patch
new file mode 100644 (file)
index 0000000..4cf9b2c
--- /dev/null
@@ -0,0 +1,72 @@
+From f8e7dfd6fdabb831846ab1970a875746559d491b Mon Sep 17 00:00:00 2001
+From: Vincent Whitchurch <vincent.whitchurch@axis.com>
+Date: Fri, 26 Nov 2021 16:51:15 +0100
+Subject: net: stmmac: Avoid DMA_CHAN_CONTROL write if no Split Header support
+
+From: Vincent Whitchurch <vincent.whitchurch@axis.com>
+
+commit f8e7dfd6fdabb831846ab1970a875746559d491b upstream.
+
+The driver assumes that split headers can be enabled/disabled without
+stopping/starting the device, so it writes DMA_CHAN_CONTROL from
+stmmac_set_features().  However, on my system (IP v5.10a without Split
+Header support), simply writing DMA_CHAN_CONTROL when DMA is running
+(for example, with the commands below) leads to a TX watchdog timeout.
+
+ host$ socat TCP-LISTEN:1024,fork,reuseaddr - &
+ device$ ethtool -K eth0 tso off
+ device$ ethtool -K eth0 tso on
+ device$ dd if=/dev/zero bs=1M count=10 | socat - TCP4:host:1024
+ <tx watchdog timeout>
+
+Note that since my IP is configured without Split Header support, the
+driver always just reads and writes the same value to the
+DMA_CHAN_CONTROL register.
+
+I don't have access to any platforms with Split Header support so I
+don't know if these writes to the DMA_CHAN_CONTROL while DMA is running
+actually work properly on such systems.  I could not find anything in
+the databook that says that DMA_CHAN_CONTROL should not be written when
+the DMA is running.
+
+But on systems without Split Header support, there is in any case no
+need to call enable_sph() in stmmac_set_features() at all since SPH can
+never be toggled, so we can avoid the watchdog timeout there by skipping
+this call.
+
+Fixes: 8c6fc097a2f4acf ("net: stmmac: gmac4+: Add Split Header support")
+Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |   11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -5531,8 +5531,6 @@ static int stmmac_set_features(struct ne
+                              netdev_features_t features)
+ {
+       struct stmmac_priv *priv = netdev_priv(netdev);
+-      bool sph_en;
+-      u32 chan;
+       /* Keep the COE Type in case of csum is supporting */
+       if (features & NETIF_F_RXCSUM)
+@@ -5544,10 +5542,13 @@ static int stmmac_set_features(struct ne
+        */
+       stmmac_rx_ipc(priv, priv->hw);
+-      sph_en = (priv->hw->rx_csum > 0) && priv->sph;
++      if (priv->sph_cap) {
++              bool sph_en = (priv->hw->rx_csum > 0) && priv->sph;
++              u32 chan;
+-      for (chan = 0; chan < priv->plat->rx_queues_to_use; chan++)
+-              stmmac_enable_sph(priv, priv->ioaddr, sph_en, chan);
++              for (chan = 0; chan < priv->plat->rx_queues_to_use; chan++)
++                      stmmac_enable_sph(priv, priv->ioaddr, sph_en, chan);
++      }
+       return 0;
+ }
diff --git a/queue-5.15/net-usb-lan78xx-lan78xx_phy_init-use-phy_poll-instead-of-0-if-no-irq-is-available.patch b/queue-5.15/net-usb-lan78xx-lan78xx_phy_init-use-phy_poll-instead-of-0-if-no-irq-is-available.patch
new file mode 100644 (file)
index 0000000..5888e49
--- /dev/null
@@ -0,0 +1,33 @@
+From 817b653160db9852d5a0498a31f047e18ce27e5b Mon Sep 17 00:00:00 2001
+From: Sven Schuchmann <schuchmann@schleissheimer.de>
+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 <schuchmann@schleissheimer.de>
+
+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 <andrew@lunn.ch>
+Signed-off-by: Sven Schuchmann <schuchmann@schleissheimer.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -2228,7 +2228,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.15/octeontx2-af-fix-a-memleak-bug-in-rvu_mbox_init.patch b/queue-5.15/octeontx2-af-fix-a-memleak-bug-in-rvu_mbox_init.patch
new file mode 100644 (file)
index 0000000..1de6665
--- /dev/null
@@ -0,0 +1,50 @@
+From e07a097b4986afb8f925d0bb32612e1d3e88ce15 Mon Sep 17 00:00:00 2001
+From: Zhou Qingyang <zhou1615@umn.edu>
+Date: Wed, 1 Dec 2021 00:50:39 +0800
+Subject: octeontx2-af: Fix a memleak bug in rvu_mbox_init()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zhou Qingyang <zhou1615@umn.edu>
+
+commit e07a097b4986afb8f925d0bb32612e1d3e88ce15 upstream.
+
+In rvu_mbox_init(), mbox_regions is not freed or passed out
+under the switch-default region, which could lead to a memory leak.
+
+Fix this bug by changing 'return err' to 'goto free_regions'.
+
+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_OCTEONTX2_AF=y show no new warnings,
+and our static analyzer no longer warns about this code.
+
+Fixes: 98c561116360 (“octeontx2-af: cn10k: Add mbox support for CN10K platform”)
+Signed-off-by: Zhou Qingyang <zhou1615@umn.edu>
+Link: https://lore.kernel.org/r/20211130165039.192426-1-zhou1615@umn.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/af/rvu.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+@@ -2281,7 +2281,7 @@ static int rvu_mbox_init(struct rvu *rvu
+                       goto free_regions;
+               break;
+       default:
+-              return err;
++              goto free_regions;
+       }
+       mw->mbox_wq = alloc_workqueue(name,
diff --git a/queue-5.15/rxrpc-fix-rxrpc_local-leak-in-rxrpc_lookup_peer.patch b/queue-5.15/rxrpc-fix-rxrpc_local-leak-in-rxrpc_lookup_peer.patch
new file mode 100644 (file)
index 0000000..4082464
--- /dev/null
@@ -0,0 +1,69 @@
+From beacff50edbd6c9659a6f15fc7f6126909fade29 Mon Sep 17 00:00:00 2001
+From: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
+Date: Sun, 21 Nov 2021 04:16:08 +0000
+Subject: rxrpc: Fix rxrpc_local leak in rxrpc_lookup_peer()
+
+From: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
+
+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 <eiichi.tsukata@nutanix.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Marc Dionne <marc.dionne@auristor.com>
+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 <gregkh@linuxfoundation.org>
+---
+ 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.15/rxrpc-fix-rxrpc_peer-leak-in-rxrpc_look_up_bundle.patch b/queue-5.15/rxrpc-fix-rxrpc_peer-leak-in-rxrpc_look_up_bundle.patch
new file mode 100644 (file)
index 0000000..5222f64
--- /dev/null
@@ -0,0 +1,61 @@
+From ca77fba821351190777b236ce749d7c4d353102e Mon Sep 17 00:00:00 2001
+From: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
+Date: Sun, 21 Nov 2021 04:16:07 +0000
+Subject: rxrpc: Fix rxrpc_peer leak in rxrpc_look_up_bundle()
+
+From: Eiichi Tsukata <eiichi.tsukata@nutanix.com>
+
+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 <eiichi.tsukata@nutanix.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Marc Dionne <marc.dionne@auristor.com>
+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 <gregkh@linuxfoundation.org>
+---
+ 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);
+ }
+ /*
+@@ -328,7 +332,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.15/selftests-net-correct-case-name.patch b/queue-5.15/selftests-net-correct-case-name.patch
new file mode 100644 (file)
index 0000000..53087e1
--- /dev/null
@@ -0,0 +1,34 @@
+From a05431b22be819d75db72ca3d44381d18a37b092 Mon Sep 17 00:00:00 2001
+From: Li Zhijian <lizhijian@cn.fujitsu.com>
+Date: Thu, 2 Dec 2021 10:28:41 +0800
+Subject: selftests: net: Correct case name
+
+From: Li Zhijian <lizhijian@cn.fujitsu.com>
+
+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 <lizhijian@cn.fujitsu.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -4002,8 +4002,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
index a8130e1de0c45e2bfd0d50c572a078e371271e8f..606b8ff29a28386ba4ec8efb137e78ca54aaf381 100644 (file)
@@ -105,3 +105,40 @@ 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
+iwlwifi-fix-warnings-produced-by-kernel-debug-options.patch
+net-mlx5e-ipsec-fix-software-parser-inner-l3-type-setting-in-case-of-encapsulation.patch
+net-mlx4_en-fix-an-use-after-free-bug-in-mlx4_en_try_alloc_resources.patch
+selftests-net-correct-case-name.patch
+net-dsa-b53-add-spi-id-table.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-stmmac-avoid-dma_chan_control-write-if-no-split-header-support.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
+octeontx2-af-fix-a-memleak-bug-in-rvu_mbox_init.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
+drm-vc4-kms-wait-for-the-commit-before-increasing-our-clock-rate.patch
+drm-vc4-kms-fix-return-code-check.patch
+drm-vc4-kms-add-missing-drm_crtc_commit_put.patch
+drm-vc4-kms-clear-the-hvs-fifo-commit-pointer-once-done.patch
+drm-vc4-kms-don-t-duplicate-pending-commit.patch
+drm-vc4-kms-fix-previous-hvs-commit-wait.patch