]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 23 Jul 2023 14:13:16 +0000 (16:13 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 23 Jul 2023 14:13:16 +0000 (16:13 +0200)
added patches:
accel-qaic-add-consistent-integer-overflow-checks.patch
accel-qaic-tighten-bounds-checking-in-decode_message.patch
accel-qaic-tighten-bounds-checking-in-encode_message.patch
arm64-fpsimd-ensure-sme-storage-is-allocated-after-sve-vl-changes.patch
asoc-codecs-wcd-mbhc-v2-fix-resource-leaks-on-component-remove.patch
asoc-codecs-wcd934x-fix-resource-leaks-on-component-remove.patch
asoc-codecs-wcd938x-fix-codec-initialisation-race.patch
asoc-codecs-wcd938x-fix-missing-clsh-ctrl-error-handling.patch
asoc-codecs-wcd938x-fix-missing-mbhc-init-error-handling.patch
asoc-codecs-wcd938x-fix-resource-leaks-on-component-remove.patch
asoc-codecs-wcd938x-fix-soundwire-initialisation-race.patch
asoc-cs35l45-select-regmap_irq.patch
asoc-cs42l51-fix-driver-to-properly-autoload-with-automatic-module-loading.patch
asoc-fsl_sai-disable-bit-clock-with-transmitter.patch
asoc-fsl_sai-revert-asoc-fsl_sai-enable-mctl_mclk_en-bit-for-master-mode.patch
asoc-qdsp6-audioreach-fix-topology-probe-deferral.patch
asoc-rt5640-fix-sleep-in-atomic-context.patch
asoc-tegra-fix-adx-byte-map.patch
asoc-tegra-fix-amx-byte-map.patch
can-bcm-fix-uaf-in-bcm_proc_show.patch
can-gs_usb-fix-time-stamp-counter-initialization.patch
can-gs_usb-gs_can_open-improve-error-handling.patch
can-mcp251xfd-__mcp251xfd_chip_set_mode-increase-poll-timeout.patch
can-raw-fix-receiver-memory-leak.patch
dma-buf-dma-resv-stop-leaking-on-krealloc-failure.patch
drm-amd-display-check-tg-is-non-null-before-checking-if-enabled.patch
drm-amd-display-disable-mpc-split-by-default-on-special-asic.patch
drm-amd-display-keep-phy-active-for-dp-displays-on-dcn31.patch
drm-amd-display-only-accept-async-flips-for-fast-updates.patch
drm-amdgpu-pm-make-gfxclock-consistent-for-sienna-cichlid.patch
drm-amdgpu-pm-make-mclk-consistent-for-smu-13.0.7.patch
drm-amdgpu-vkms-relax-timer-deactivation-by-hrtimer_try_to_cancel.patch
drm-client-fix-memory-leak-in-drm_client_modeset_probe.patch
drm-client-fix-memory-leak-in-drm_client_target_cloned.patch
drm-nouveau-disp-pior-dp-uses-gpio-for-hpd-not-pmgr-aux-interrupts.patch
drm-nouveau-i2c-fix-number-of-aux-event-slots.patch
drm-nouveau-kms-nv50-init-hpd_irq_lock-for-pior-dp.patch
ia64-mmap-consider-pgoff-when-searching-for-free-mapping.patch
of-preserve-of-display-device-name-for-compatibility.patch
regmap-account-for-register-length-in-smbus-i-o-limits.patch
regmap-drop-initial-version-of-maximum-transfer-length-fixes.patch
revert-r8169-disable-aspm-during-napi-poll.patch
s390-zcrypt-fix-reply-buffer-calculations-for-cca-replies.patch
selftests-tc-add-conntrack-procfs-kconfig.patch

45 files changed:
queue-6.4/accel-qaic-add-consistent-integer-overflow-checks.patch [new file with mode: 0644]
queue-6.4/accel-qaic-tighten-bounds-checking-in-decode_message.patch [new file with mode: 0644]
queue-6.4/accel-qaic-tighten-bounds-checking-in-encode_message.patch [new file with mode: 0644]
queue-6.4/arm64-fpsimd-ensure-sme-storage-is-allocated-after-sve-vl-changes.patch [new file with mode: 0644]
queue-6.4/asoc-codecs-wcd-mbhc-v2-fix-resource-leaks-on-component-remove.patch [new file with mode: 0644]
queue-6.4/asoc-codecs-wcd934x-fix-resource-leaks-on-component-remove.patch [new file with mode: 0644]
queue-6.4/asoc-codecs-wcd938x-fix-codec-initialisation-race.patch [new file with mode: 0644]
queue-6.4/asoc-codecs-wcd938x-fix-missing-clsh-ctrl-error-handling.patch [new file with mode: 0644]
queue-6.4/asoc-codecs-wcd938x-fix-missing-mbhc-init-error-handling.patch [new file with mode: 0644]
queue-6.4/asoc-codecs-wcd938x-fix-resource-leaks-on-component-remove.patch [new file with mode: 0644]
queue-6.4/asoc-codecs-wcd938x-fix-soundwire-initialisation-race.patch [new file with mode: 0644]
queue-6.4/asoc-cs35l45-select-regmap_irq.patch [new file with mode: 0644]
queue-6.4/asoc-cs42l51-fix-driver-to-properly-autoload-with-automatic-module-loading.patch [new file with mode: 0644]
queue-6.4/asoc-fsl_sai-disable-bit-clock-with-transmitter.patch [new file with mode: 0644]
queue-6.4/asoc-fsl_sai-revert-asoc-fsl_sai-enable-mctl_mclk_en-bit-for-master-mode.patch [new file with mode: 0644]
queue-6.4/asoc-qdsp6-audioreach-fix-topology-probe-deferral.patch [new file with mode: 0644]
queue-6.4/asoc-rt5640-fix-sleep-in-atomic-context.patch [new file with mode: 0644]
queue-6.4/asoc-tegra-fix-adx-byte-map.patch [new file with mode: 0644]
queue-6.4/asoc-tegra-fix-amx-byte-map.patch [new file with mode: 0644]
queue-6.4/can-bcm-fix-uaf-in-bcm_proc_show.patch [new file with mode: 0644]
queue-6.4/can-gs_usb-fix-time-stamp-counter-initialization.patch [new file with mode: 0644]
queue-6.4/can-gs_usb-gs_can_open-improve-error-handling.patch [new file with mode: 0644]
queue-6.4/can-mcp251xfd-__mcp251xfd_chip_set_mode-increase-poll-timeout.patch [new file with mode: 0644]
queue-6.4/can-raw-fix-receiver-memory-leak.patch [new file with mode: 0644]
queue-6.4/dma-buf-dma-resv-stop-leaking-on-krealloc-failure.patch [new file with mode: 0644]
queue-6.4/drm-amd-display-check-tg-is-non-null-before-checking-if-enabled.patch [new file with mode: 0644]
queue-6.4/drm-amd-display-disable-mpc-split-by-default-on-special-asic.patch [new file with mode: 0644]
queue-6.4/drm-amd-display-keep-phy-active-for-dp-displays-on-dcn31.patch [new file with mode: 0644]
queue-6.4/drm-amd-display-only-accept-async-flips-for-fast-updates.patch [new file with mode: 0644]
queue-6.4/drm-amdgpu-pm-make-gfxclock-consistent-for-sienna-cichlid.patch [new file with mode: 0644]
queue-6.4/drm-amdgpu-pm-make-mclk-consistent-for-smu-13.0.7.patch [new file with mode: 0644]
queue-6.4/drm-amdgpu-vkms-relax-timer-deactivation-by-hrtimer_try_to_cancel.patch [new file with mode: 0644]
queue-6.4/drm-client-fix-memory-leak-in-drm_client_modeset_probe.patch [new file with mode: 0644]
queue-6.4/drm-client-fix-memory-leak-in-drm_client_target_cloned.patch [new file with mode: 0644]
queue-6.4/drm-nouveau-disp-pior-dp-uses-gpio-for-hpd-not-pmgr-aux-interrupts.patch [new file with mode: 0644]
queue-6.4/drm-nouveau-i2c-fix-number-of-aux-event-slots.patch [new file with mode: 0644]
queue-6.4/drm-nouveau-kms-nv50-init-hpd_irq_lock-for-pior-dp.patch [new file with mode: 0644]
queue-6.4/ia64-mmap-consider-pgoff-when-searching-for-free-mapping.patch [new file with mode: 0644]
queue-6.4/of-preserve-of-display-device-name-for-compatibility.patch [new file with mode: 0644]
queue-6.4/regmap-account-for-register-length-in-smbus-i-o-limits.patch [new file with mode: 0644]
queue-6.4/regmap-drop-initial-version-of-maximum-transfer-length-fixes.patch [new file with mode: 0644]
queue-6.4/revert-r8169-disable-aspm-during-napi-poll.patch [new file with mode: 0644]
queue-6.4/s390-zcrypt-fix-reply-buffer-calculations-for-cca-replies.patch [new file with mode: 0644]
queue-6.4/selftests-tc-add-conntrack-procfs-kconfig.patch [new file with mode: 0644]
queue-6.4/series

diff --git a/queue-6.4/accel-qaic-add-consistent-integer-overflow-checks.patch b/queue-6.4/accel-qaic-add-consistent-integer-overflow-checks.patch
new file mode 100644 (file)
index 0000000..c18b81f
--- /dev/null
@@ -0,0 +1,70 @@
+From 47d87f71d00b7091b43a56f608f7151b33e5772e Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@linaro.org>
+Date: Tue, 11 Jul 2023 11:21:00 +0300
+Subject: accel/qaic: Add consistent integer overflow checks
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+commit 47d87f71d00b7091b43a56f608f7151b33e5772e upstream.
+
+The encode_dma() function has integer overflow checks.  The
+encode_passthrough(), encode_activate() and encode_status() functions
+did not.  I added integer overflow checking everywhere.  I also
+updated the integer overflow checking in encode_dma() to use size_add()
+so everything is consistent.
+
+Fixes: 129776ac2e38 ("accel/qaic: Add control path")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Pranjal Ramajor Asha Kanojiya <quic_pkanojiy@quicinc.com>
+Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Cc: stable@vger.kernel.org # 6.4.x
+[jhugo: tweak if in encode_dma() to match existing style]
+Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/ZK0Q7IsPkj6WSCcL@moroto
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/accel/qaic/qaic_control.c |   11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+--- a/drivers/accel/qaic/qaic_control.c
++++ b/drivers/accel/qaic/qaic_control.c
+@@ -367,7 +367,7 @@ static int encode_passthrough(struct qai
+       if (in_trans->hdr.len % 8 != 0)
+               return -EINVAL;
+-      if (msg_hdr_len + in_trans->hdr.len > QAIC_MANAGE_EXT_MSG_LENGTH)
++      if (size_add(msg_hdr_len, in_trans->hdr.len) > QAIC_MANAGE_EXT_MSG_LENGTH)
+               return -ENOSPC;
+       trans_wrapper = add_wrapper(wrappers,
+@@ -561,11 +561,8 @@ static int encode_dma(struct qaic_device
+       msg = &wrapper->msg;
+       msg_hdr_len = le32_to_cpu(msg->hdr.len);
+-      if (msg_hdr_len > (UINT_MAX - QAIC_MANAGE_EXT_MSG_LENGTH))
+-              return -EINVAL;
+-
+       /* There should be enough space to hold at least one ASP entry. */
+-      if (msg_hdr_len + sizeof(*out_trans) + sizeof(struct wire_addr_size_pair) >
++      if (size_add(msg_hdr_len, sizeof(*out_trans) + sizeof(struct wire_addr_size_pair)) >
+           QAIC_MANAGE_EXT_MSG_LENGTH)
+               return -ENOMEM;
+@@ -638,7 +635,7 @@ static int encode_activate(struct qaic_d
+       msg = &wrapper->msg;
+       msg_hdr_len = le32_to_cpu(msg->hdr.len);
+-      if (msg_hdr_len + sizeof(*out_trans) > QAIC_MANAGE_MAX_MSG_LENGTH)
++      if (size_add(msg_hdr_len, sizeof(*out_trans)) > QAIC_MANAGE_MAX_MSG_LENGTH)
+               return -ENOSPC;
+       if (!in_trans->queue_size)
+@@ -722,7 +719,7 @@ static int encode_status(struct qaic_dev
+       msg = &wrapper->msg;
+       msg_hdr_len = le32_to_cpu(msg->hdr.len);
+-      if (msg_hdr_len + in_trans->hdr.len > QAIC_MANAGE_MAX_MSG_LENGTH)
++      if (size_add(msg_hdr_len, in_trans->hdr.len) > QAIC_MANAGE_MAX_MSG_LENGTH)
+               return -ENOSPC;
+       trans_wrapper = add_wrapper(wrappers, sizeof(*trans_wrapper));
diff --git a/queue-6.4/accel-qaic-tighten-bounds-checking-in-decode_message.patch b/queue-6.4/accel-qaic-tighten-bounds-checking-in-decode_message.patch
new file mode 100644 (file)
index 0000000..430e82f
--- /dev/null
@@ -0,0 +1,76 @@
+From 51b56382ed2a2b03347372272362b3baa623ed1e Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@linaro.org>
+Date: Tue, 11 Jul 2023 11:20:54 +0300
+Subject: accel/qaic: tighten bounds checking in decode_message()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+commit 51b56382ed2a2b03347372272362b3baa623ed1e upstream.
+
+Copy the bounds checking from encode_message() to decode_message().
+
+This patch addresses the following concerns.  Ensure that there is
+enough space for at least one header so that we don't have a negative
+size later.
+
+       if (msg_hdr_len < sizeof(*trans_hdr))
+
+Ensure that we have enough space to read the next header from the
+msg->data.
+
+       if (msg_len > msg_hdr_len - sizeof(*trans_hdr))
+               return -EINVAL;
+
+Check that the trans_hdr->len is not below the minimum size:
+
+       if (hdr_len < sizeof(*trans_hdr))
+
+This minimum check ensures that we don't corrupt memory in
+decode_passthrough() when we do.
+
+       memcpy(out_trans->data, in_trans->data, len - sizeof(in_trans->hdr));
+
+And finally, use size_add() to prevent an integer overflow:
+
+       if (size_add(msg_len, hdr_len) > msg_hdr_len)
+
+Fixes: 129776ac2e38 ("accel/qaic: Add control path")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Pranjal Ramajor Asha Kanojiya <quic_pkanojiy@quicinc.com>
+Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Cc: stable@vger.kernel.org # 6.4.x
+Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/ZK0Q5nbLyDO7kJa+@moroto
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/accel/qaic/qaic_control.c |   12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/accel/qaic/qaic_control.c
++++ b/drivers/accel/qaic/qaic_control.c
+@@ -959,15 +959,23 @@ static int decode_message(struct qaic_de
+       int ret;
+       int i;
+-      if (msg_hdr_len > QAIC_MANAGE_MAX_MSG_LENGTH)
++      if (msg_hdr_len < sizeof(*trans_hdr) ||
++          msg_hdr_len > QAIC_MANAGE_MAX_MSG_LENGTH)
+               return -EINVAL;
+       user_msg->len = 0;
+       user_msg->count = le32_to_cpu(msg->hdr.count);
+       for (i = 0; i < user_msg->count; ++i) {
++              u32 hdr_len;
++
++              if (msg_len > msg_hdr_len - sizeof(*trans_hdr))
++                      return -EINVAL;
++
+               trans_hdr = (struct wire_trans_hdr *)(msg->data + msg_len);
+-              if (msg_len + le32_to_cpu(trans_hdr->len) > msg_hdr_len)
++              hdr_len = le32_to_cpu(trans_hdr->len);
++              if (hdr_len < sizeof(*trans_hdr) ||
++                  size_add(msg_len, hdr_len) > msg_hdr_len)
+                       return -EINVAL;
+               switch (le32_to_cpu(trans_hdr->type)) {
diff --git a/queue-6.4/accel-qaic-tighten-bounds-checking-in-encode_message.patch b/queue-6.4/accel-qaic-tighten-bounds-checking-in-encode_message.patch
new file mode 100644 (file)
index 0000000..5c73af3
--- /dev/null
@@ -0,0 +1,88 @@
+From ea33cb6fc2788f9fe248d49e1c0b2553a58436ef Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@linaro.org>
+Date: Tue, 11 Jul 2023 11:20:44 +0300
+Subject: accel/qaic: tighten bounds checking in encode_message()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+commit ea33cb6fc2788f9fe248d49e1c0b2553a58436ef upstream.
+
+There are several issues in this code.  The check at the start of the
+loop:
+
+       if (user_len >= user_msg->len) {
+
+This check does not ensure that we have enough space for the trans_hdr
+(8 bytes).  Instead the check needs to be:
+
+       if (user_len > user_msg->len - sizeof(*trans_hdr)) {
+
+That subtraction is done as an unsigned long we want to avoid
+negatives.  Add a lower bound to the start of the function.
+
+       if (user_msg->len < sizeof(*trans_hdr))
+
+There is a second integer underflow which can happen if
+trans_hdr->len is zero inside the encode_passthrough() function.
+
+       memcpy(out_trans->data, in_trans->data, in_trans->hdr.len - sizeof(in_trans->hdr));
+
+Instead of adding a check to encode_passthrough() it's better to check
+in this central place.  Add that check:
+
+       if (trans_hdr->len < sizeof(trans_hdr)
+
+The final concern is that the "user_len + trans_hdr->len" might have an
+integer overflow bug.  Use size_add() to prevent that.
+
+-      if (user_len + trans_hdr->len > user_msg->len) {
++      if (size_add(user_len, trans_hdr->len) > user_msg->len) {
+
+Fixes: 129776ac2e38 ("accel/qaic: Add control path")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Pranjal Ramajor Asha Kanojiya <quic_pkanojiy@quicinc.com>
+Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Cc: stable@vger.kernel.org # 6.4.x
+Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/9a0cb0c1-a974-4f10-bc8d-94437983639a@moroto.mountain
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/accel/qaic/qaic_control.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/accel/qaic/qaic_control.c
++++ b/drivers/accel/qaic/qaic_control.c
+@@ -14,6 +14,7 @@
+ #include <linux/mm.h>
+ #include <linux/moduleparam.h>
+ #include <linux/mutex.h>
++#include <linux/overflow.h>
+ #include <linux/pci.h>
+ #include <linux/scatterlist.h>
+ #include <linux/types.h>
+@@ -751,7 +752,8 @@ static int encode_message(struct qaic_de
+       int ret;
+       int i;
+-      if (!user_msg->count) {
++      if (!user_msg->count ||
++          user_msg->len < sizeof(*trans_hdr)) {
+               ret = -EINVAL;
+               goto out;
+       }
+@@ -768,12 +770,13 @@ static int encode_message(struct qaic_de
+       }
+       for (i = 0; i < user_msg->count; ++i) {
+-              if (user_len >= user_msg->len) {
++              if (user_len > user_msg->len - sizeof(*trans_hdr)) {
+                       ret = -EINVAL;
+                       break;
+               }
+               trans_hdr = (struct qaic_manage_trans_hdr *)(user_msg->data + user_len);
+-              if (user_len + trans_hdr->len > user_msg->len) {
++              if (trans_hdr->len < sizeof(trans_hdr) ||
++                  size_add(user_len, trans_hdr->len) > user_msg->len) {
+                       ret = -EINVAL;
+                       break;
+               }
diff --git a/queue-6.4/arm64-fpsimd-ensure-sme-storage-is-allocated-after-sve-vl-changes.patch b/queue-6.4/arm64-fpsimd-ensure-sme-storage-is-allocated-after-sve-vl-changes.patch
new file mode 100644 (file)
index 0000000..0287ad8
--- /dev/null
@@ -0,0 +1,93 @@
+From d4d5be94a87872421ea2569044092535aff0b886 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@kernel.org>
+Date: Thu, 20 Jul 2023 19:38:58 +0100
+Subject: arm64/fpsimd: Ensure SME storage is allocated after SVE VL changes
+
+From: Mark Brown <broonie@kernel.org>
+
+commit d4d5be94a87872421ea2569044092535aff0b886 upstream.
+
+When we reconfigure the SVE vector length we discard the backing storage
+for the SVE vectors and then reallocate on next SVE use, leaving the SME
+specific state alone. This means that we do not enable SME traps if they
+were already disabled. That means that userspace code can enter streaming
+mode without trapping, putting the task in a state where if we try to save
+the state of the task we will fault.
+
+Since the ABI does not specify that changing the SVE vector length disturbs
+SME state, and since SVE code may not be aware of SME code in the process,
+we shouldn't simply discard any ZA state. Instead immediately reallocate
+the storage for SVE, and disable SME if we change the SVE vector length
+while there is no SME state active.
+
+Disabling SME traps on SVE vector length changes would make the overall
+code more complex since we would have a state where we have valid SME state
+stored but might get a SME trap.
+
+Fixes: 9e4ab6c89109 ("arm64/sme: Implement vector length configuration prctl()s")
+Reported-by: David Spickett <David.Spickett@arm.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20230720-arm64-fix-sve-sme-vl-change-v2-1-8eea06b82d57@kernel.org
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kernel/fpsimd.c |   33 +++++++++++++++++++++++++--------
+ 1 file changed, 25 insertions(+), 8 deletions(-)
+
+--- a/arch/arm64/kernel/fpsimd.c
++++ b/arch/arm64/kernel/fpsimd.c
+@@ -847,6 +847,8 @@ void sve_sync_from_fpsimd_zeropad(struct
+ int vec_set_vector_length(struct task_struct *task, enum vec_type type,
+                         unsigned long vl, unsigned long flags)
+ {
++      bool free_sme = false;
++
+       if (flags & ~(unsigned long)(PR_SVE_VL_INHERIT |
+                                    PR_SVE_SET_VL_ONEXEC))
+               return -EINVAL;
+@@ -897,21 +899,36 @@ int vec_set_vector_length(struct task_st
+               task->thread.fp_type = FP_STATE_FPSIMD;
+       }
+-      if (system_supports_sme() && type == ARM64_VEC_SME) {
+-              task->thread.svcr &= ~(SVCR_SM_MASK |
+-                                     SVCR_ZA_MASK);
+-              clear_thread_flag(TIF_SME);
++      if (system_supports_sme()) {
++              if (type == ARM64_VEC_SME ||
++                  !(task->thread.svcr & (SVCR_SM_MASK | SVCR_ZA_MASK))) {
++                      /*
++                       * We are changing the SME VL or weren't using
++                       * SME anyway, discard the state and force a
++                       * reallocation.
++                       */
++                      task->thread.svcr &= ~(SVCR_SM_MASK |
++                                             SVCR_ZA_MASK);
++                      clear_thread_flag(TIF_SME);
++                      free_sme = true;
++              }
+       }
+       if (task == current)
+               put_cpu_fpsimd_context();
+       /*
+-       * Force reallocation of task SVE and SME state to the correct
+-       * size on next use:
++       * Free the changed states if they are not in use, SME will be
++       * reallocated to the correct size on next use and we just
++       * allocate SVE now in case it is needed for use in streaming
++       * mode.
+        */
+-      sve_free(task);
+-      if (system_supports_sme() && type == ARM64_VEC_SME)
++      if (system_supports_sve()) {
++              sve_free(task);
++              sve_alloc(task, true);
++      }
++
++      if (free_sme)
+               sme_free(task);
+       task_set_vl(task, type, vl);
diff --git a/queue-6.4/asoc-codecs-wcd-mbhc-v2-fix-resource-leaks-on-component-remove.patch b/queue-6.4/asoc-codecs-wcd-mbhc-v2-fix-resource-leaks-on-component-remove.patch
new file mode 100644 (file)
index 0000000..aabe426
--- /dev/null
@@ -0,0 +1,157 @@
+From a5475829adcc600bc69ee9ff7c9e3e43fb4f8d30 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan+linaro@kernel.org>
+Date: Wed, 5 Jul 2023 14:30:16 +0200
+Subject: ASoC: codecs: wcd-mbhc-v2: fix resource leaks on component remove
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+commit a5475829adcc600bc69ee9ff7c9e3e43fb4f8d30 upstream.
+
+The MBHC resources must be released on component probe failure and
+removal so can not be tied to the lifetime of the component device.
+
+This is specifically needed to allow probe deferrals of the sound card
+which otherwise fails when reprobing the codec component:
+
+    snd-sc8280xp sound: ASoC: failed to instantiate card -517
+    genirq: Flags mismatch irq 299. 00002001 (mbhc sw intr) vs. 00002001 (mbhc sw intr)
+    wcd938x_codec audio-codec: Failed to request mbhc interrupts -16
+    wcd938x_codec audio-codec: mbhc initialization failed
+    wcd938x_codec audio-codec: ASoC: error at snd_soc_component_probe on audio-codec: -16
+    snd-sc8280xp sound: ASoC: failed to instantiate card -16
+
+Fixes: 0e5c9e7ff899 ("ASoC: codecs: wcd: add multi button Headset detection support")
+Cc: stable@vger.kernel.org      # 5.14
+Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20230705123018.30903-7-johan+linaro@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/codecs/wcd-mbhc-v2.c |   57 +++++++++++++++++++++++++++++------------
+ 1 file changed, 41 insertions(+), 16 deletions(-)
+
+--- a/sound/soc/codecs/wcd-mbhc-v2.c
++++ b/sound/soc/codecs/wcd-mbhc-v2.c
+@@ -1454,7 +1454,7 @@ struct wcd_mbhc *wcd_mbhc_init(struct sn
+               return ERR_PTR(-EINVAL);
+       }
+-      mbhc = devm_kzalloc(dev, sizeof(*mbhc), GFP_KERNEL);
++      mbhc = kzalloc(sizeof(*mbhc), GFP_KERNEL);
+       if (!mbhc)
+               return ERR_PTR(-ENOMEM);
+@@ -1474,61 +1474,76 @@ struct wcd_mbhc *wcd_mbhc_init(struct sn
+       INIT_WORK(&mbhc->correct_plug_swch, wcd_correct_swch_plug);
+-      ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_sw_intr, NULL,
++      ret = request_threaded_irq(mbhc->intr_ids->mbhc_sw_intr, NULL,
+                                       wcd_mbhc_mech_plug_detect_irq,
+                                       IRQF_ONESHOT | IRQF_TRIGGER_RISING,
+                                       "mbhc sw intr", mbhc);
+       if (ret)
+-              goto err;
++              goto err_free_mbhc;
+-      ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_btn_press_intr, NULL,
++      ret = request_threaded_irq(mbhc->intr_ids->mbhc_btn_press_intr, NULL,
+                                       wcd_mbhc_btn_press_handler,
+                                       IRQF_ONESHOT | IRQF_TRIGGER_RISING,
+                                       "Button Press detect", mbhc);
+       if (ret)
+-              goto err;
++              goto err_free_sw_intr;
+-      ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_btn_release_intr, NULL,
++      ret = request_threaded_irq(mbhc->intr_ids->mbhc_btn_release_intr, NULL,
+                                       wcd_mbhc_btn_release_handler,
+                                       IRQF_ONESHOT | IRQF_TRIGGER_RISING,
+                                       "Button Release detect", mbhc);
+       if (ret)
+-              goto err;
++              goto err_free_btn_press_intr;
+-      ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_hs_ins_intr, NULL,
++      ret = request_threaded_irq(mbhc->intr_ids->mbhc_hs_ins_intr, NULL,
+                                       wcd_mbhc_adc_hs_ins_irq,
+                                       IRQF_ONESHOT | IRQF_TRIGGER_RISING,
+                                       "Elect Insert", mbhc);
+       if (ret)
+-              goto err;
++              goto err_free_btn_release_intr;
+       disable_irq_nosync(mbhc->intr_ids->mbhc_hs_ins_intr);
+-      ret = devm_request_threaded_irq(dev, mbhc->intr_ids->mbhc_hs_rem_intr, NULL,
++      ret = request_threaded_irq(mbhc->intr_ids->mbhc_hs_rem_intr, NULL,
+                                       wcd_mbhc_adc_hs_rem_irq,
+                                       IRQF_ONESHOT | IRQF_TRIGGER_RISING,
+                                       "Elect Remove", mbhc);
+       if (ret)
+-              goto err;
++              goto err_free_hs_ins_intr;
+       disable_irq_nosync(mbhc->intr_ids->mbhc_hs_rem_intr);
+-      ret = devm_request_threaded_irq(dev, mbhc->intr_ids->hph_left_ocp, NULL,
++      ret = request_threaded_irq(mbhc->intr_ids->hph_left_ocp, NULL,
+                                       wcd_mbhc_hphl_ocp_irq,
+                                       IRQF_ONESHOT | IRQF_TRIGGER_RISING,
+                                       "HPH_L OCP detect", mbhc);
+       if (ret)
+-              goto err;
++              goto err_free_hs_rem_intr;
+-      ret = devm_request_threaded_irq(dev, mbhc->intr_ids->hph_right_ocp, NULL,
++      ret = request_threaded_irq(mbhc->intr_ids->hph_right_ocp, NULL,
+                                       wcd_mbhc_hphr_ocp_irq,
+                                       IRQF_ONESHOT | IRQF_TRIGGER_RISING,
+                                       "HPH_R OCP detect", mbhc);
+       if (ret)
+-              goto err;
++              goto err_free_hph_left_ocp;
+       return mbhc;
+-err:
++
++err_free_hph_left_ocp:
++      free_irq(mbhc->intr_ids->hph_left_ocp, mbhc);
++err_free_hs_rem_intr:
++      free_irq(mbhc->intr_ids->mbhc_hs_rem_intr, mbhc);
++err_free_hs_ins_intr:
++      free_irq(mbhc->intr_ids->mbhc_hs_ins_intr, mbhc);
++err_free_btn_release_intr:
++      free_irq(mbhc->intr_ids->mbhc_btn_release_intr, mbhc);
++err_free_btn_press_intr:
++      free_irq(mbhc->intr_ids->mbhc_btn_press_intr, mbhc);
++err_free_sw_intr:
++      free_irq(mbhc->intr_ids->mbhc_sw_intr, mbhc);
++err_free_mbhc:
++      kfree(mbhc);
++
+       dev_err(dev, "Failed to request mbhc interrupts %d\n", ret);
+       return ERR_PTR(ret);
+@@ -1537,9 +1552,19 @@ EXPORT_SYMBOL(wcd_mbhc_init);
+ void wcd_mbhc_deinit(struct wcd_mbhc *mbhc)
+ {
++      free_irq(mbhc->intr_ids->hph_right_ocp, mbhc);
++      free_irq(mbhc->intr_ids->hph_left_ocp, mbhc);
++      free_irq(mbhc->intr_ids->mbhc_hs_rem_intr, mbhc);
++      free_irq(mbhc->intr_ids->mbhc_hs_ins_intr, mbhc);
++      free_irq(mbhc->intr_ids->mbhc_btn_release_intr, mbhc);
++      free_irq(mbhc->intr_ids->mbhc_btn_press_intr, mbhc);
++      free_irq(mbhc->intr_ids->mbhc_sw_intr, mbhc);
++
+       mutex_lock(&mbhc->lock);
+       wcd_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch);
+       mutex_unlock(&mbhc->lock);
++
++      kfree(mbhc);
+ }
+ EXPORT_SYMBOL(wcd_mbhc_deinit);
diff --git a/queue-6.4/asoc-codecs-wcd934x-fix-resource-leaks-on-component-remove.patch b/queue-6.4/asoc-codecs-wcd934x-fix-resource-leaks-on-component-remove.patch
new file mode 100644 (file)
index 0000000..c86cf27
--- /dev/null
@@ -0,0 +1,54 @@
+From 798590cc7d3c2b5f3a7548d96dd4d8a081c1bc39 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan+linaro@kernel.org>
+Date: Wed, 5 Jul 2023 14:30:15 +0200
+Subject: ASoC: codecs: wcd934x: fix resource leaks on component remove
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+commit 798590cc7d3c2b5f3a7548d96dd4d8a081c1bc39 upstream.
+
+Make sure to release allocated MBHC resources also on component remove.
+
+This is specifically needed to allow probe deferrals of the sound card
+which otherwise fails when reprobing the codec component.
+
+Fixes: 9fb9b1690f0b ("ASoC: codecs: wcd934x: add mbhc support")
+Cc: stable@vger.kernel.org      # 5.14
+Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20230705123018.30903-6-johan+linaro@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/codecs/wcd934x.c |   12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/sound/soc/codecs/wcd934x.c
++++ b/sound/soc/codecs/wcd934x.c
+@@ -3044,6 +3044,17 @@ static int wcd934x_mbhc_init(struct snd_
+       return 0;
+ }
++
++static void wcd934x_mbhc_deinit(struct snd_soc_component *component)
++{
++      struct wcd934x_codec *wcd = snd_soc_component_get_drvdata(component);
++
++      if (!wcd->mbhc)
++              return;
++
++      wcd_mbhc_deinit(wcd->mbhc);
++}
++
+ static int wcd934x_comp_probe(struct snd_soc_component *component)
+ {
+       struct wcd934x_codec *wcd = dev_get_drvdata(component->dev);
+@@ -3077,6 +3088,7 @@ static void wcd934x_comp_remove(struct s
+ {
+       struct wcd934x_codec *wcd = dev_get_drvdata(comp->dev);
++      wcd934x_mbhc_deinit(comp);
+       wcd_clsh_ctrl_free(wcd->clsh_ctrl);
+ }
diff --git a/queue-6.4/asoc-codecs-wcd938x-fix-codec-initialisation-race.patch b/queue-6.4/asoc-codecs-wcd938x-fix-codec-initialisation-race.patch
new file mode 100644 (file)
index 0000000..3e47419
--- /dev/null
@@ -0,0 +1,54 @@
+From 85a61b1ce461a3f62f1019e5e6423c393c542bff Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan+linaro@kernel.org>
+Date: Fri, 30 Jun 2023 14:03:18 +0200
+Subject: ASoC: codecs: wcd938x: fix codec initialisation race
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+commit 85a61b1ce461a3f62f1019e5e6423c393c542bff upstream.
+
+Make sure to resume the codec and soundwire device before trying to read
+the codec variant and configure the device during component probe.
+
+This specifically avoids interpreting (a masked and shifted) -EBUSY
+errno as the variant:
+
+       wcd938x_codec audio-codec: ASoC: error at soc_component_read_no_lock on audio-codec for register: [0x000034b0] -16
+
+when the soundwire device happens to be suspended, which in turn
+prevents some headphone controls from being registered.
+
+Fixes: 8d78602aa87a ("ASoC: codecs: wcd938x: add basic driver")
+Cc: stable@vger.kernel.org      # 5.14
+Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Reported-by: Steev Klimaszewski <steev@kali.org>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Link: https://lore.kernel.org/r/20230630120318.6571-1-johan+linaro@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/codecs/wcd938x.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/sound/soc/codecs/wcd938x.c
++++ b/sound/soc/codecs/wcd938x.c
+@@ -3095,6 +3095,10 @@ static int wcd938x_soc_codec_probe(struc
+       snd_soc_component_init_regmap(component, wcd938x->regmap);
++      ret = pm_runtime_resume_and_get(dev);
++      if (ret < 0)
++              return ret;
++
+       wcd938x->variant = snd_soc_component_read_field(component,
+                                                WCD938X_DIGITAL_EFUSE_REG_0,
+                                                WCD938X_ID_MASK);
+@@ -3112,6 +3116,8 @@ static int wcd938x_soc_codec_probe(struc
+                            (WCD938X_DIGITAL_INTR_LEVEL_0 + i), 0);
+       }
++      pm_runtime_put(dev);
++
+       wcd938x->hphr_pdm_wd_int = regmap_irq_get_virq(wcd938x->irq_chip,
+                                                      WCD938X_IRQ_HPHR_PDM_WD_INT);
+       wcd938x->hphl_pdm_wd_int = regmap_irq_get_virq(wcd938x->irq_chip,
diff --git a/queue-6.4/asoc-codecs-wcd938x-fix-missing-clsh-ctrl-error-handling.patch b/queue-6.4/asoc-codecs-wcd938x-fix-missing-clsh-ctrl-error-handling.patch
new file mode 100644 (file)
index 0000000..a2e1b76
--- /dev/null
@@ -0,0 +1,37 @@
+From ed0dd9205bf69593edb495cb4b086dbae96a3f05 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan+linaro@kernel.org>
+Date: Wed, 5 Jul 2023 14:30:13 +0200
+Subject: ASoC: codecs: wcd938x: fix missing clsh ctrl error handling
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+commit ed0dd9205bf69593edb495cb4b086dbae96a3f05 upstream.
+
+Allocation of the clash control structure may fail so add the missing
+error handling to avoid dereferencing an error pointer.
+
+Fixes: 8d78602aa87a ("ASoC: codecs: wcd938x: add basic driver")
+Cc: stable@vger.kernel.org     # 5.14
+Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20230705123018.30903-4-johan+linaro@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/codecs/wcd938x.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/sound/soc/codecs/wcd938x.c
++++ b/sound/soc/codecs/wcd938x.c
+@@ -3090,6 +3090,10 @@ static int wcd938x_soc_codec_probe(struc
+                                                WCD938X_ID_MASK);
+       wcd938x->clsh_info = wcd_clsh_ctrl_alloc(component, WCD938X);
++      if (IS_ERR(wcd938x->clsh_info)) {
++              pm_runtime_put(dev);
++              return PTR_ERR(wcd938x->clsh_info);
++      }
+       wcd938x_io_init(wcd938x);
+       /* Set all interrupts as edge triggered */
diff --git a/queue-6.4/asoc-codecs-wcd938x-fix-missing-mbhc-init-error-handling.patch b/queue-6.4/asoc-codecs-wcd938x-fix-missing-mbhc-init-error-handling.patch
new file mode 100644 (file)
index 0000000..a98d816
--- /dev/null
@@ -0,0 +1,51 @@
+From 7dfae2631bfbdebecd35fe7b472ab3cc95c9ed66 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan+linaro@kernel.org>
+Date: Mon, 3 Jul 2023 14:47:01 +0200
+Subject: ASoC: codecs: wcd938x: fix missing mbhc init error handling
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+commit 7dfae2631bfbdebecd35fe7b472ab3cc95c9ed66 upstream.
+
+MBHC initialisation can fail so add the missing error handling to avoid
+dereferencing an error pointer when later configuring the jack:
+
+    Unable to handle kernel paging request at virtual address fffffffffffffff8
+
+    pc : wcd_mbhc_start+0x28/0x380 [snd_soc_wcd_mbhc]
+    lr : wcd938x_codec_set_jack+0x28/0x48 [snd_soc_wcd938x]
+
+    Call trace:
+     wcd_mbhc_start+0x28/0x380 [snd_soc_wcd_mbhc]
+     wcd938x_codec_set_jack+0x28/0x48 [snd_soc_wcd938x]
+     snd_soc_component_set_jack+0x28/0x8c [snd_soc_core]
+     qcom_snd_wcd_jack_setup+0x7c/0x19c [snd_soc_qcom_common]
+     sc8280xp_snd_init+0x20/0x2c [snd_soc_sc8280xp]
+     snd_soc_link_init+0x28/0x90 [snd_soc_core]
+     snd_soc_bind_card+0x628/0xbfc [snd_soc_core]
+     snd_soc_register_card+0xec/0x104 [snd_soc_core]
+     devm_snd_soc_register_card+0x4c/0xa4 [snd_soc_core]
+     sc8280xp_platform_probe+0xf0/0x108 [snd_soc_sc8280xp]
+
+Fixes: bcee7ed09b8e ("ASoC: codecs: wcd938x: add Multi Button Headset Control support")
+Cc: stable@vger.kernel.org      # 5.15
+Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Link: https://lore.kernel.org/r/20230703124701.11734-1-johan+linaro@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/codecs/wcd938x.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/sound/soc/codecs/wcd938x.c
++++ b/sound/soc/codecs/wcd938x.c
+@@ -2625,6 +2625,8 @@ static int wcd938x_mbhc_init(struct snd_
+                                                    WCD938X_IRQ_HPHR_OCP_INT);
+       wcd938x->wcd_mbhc = wcd_mbhc_init(component, &mbhc_cb, intr_ids, wcd_mbhc_fields, true);
++      if (IS_ERR(wcd938x->wcd_mbhc))
++              return PTR_ERR(wcd938x->wcd_mbhc);
+       snd_soc_add_component_controls(component, impedance_detect_controls,
+                                      ARRAY_SIZE(impedance_detect_controls));
diff --git a/queue-6.4/asoc-codecs-wcd938x-fix-resource-leaks-on-component-remove.patch b/queue-6.4/asoc-codecs-wcd938x-fix-resource-leaks-on-component-remove.patch
new file mode 100644 (file)
index 0000000..40f70a7
--- /dev/null
@@ -0,0 +1,151 @@
+From a3406f87775fee986876e03f93a84385f54d5999 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan+linaro@kernel.org>
+Date: Wed, 5 Jul 2023 14:30:14 +0200
+Subject: ASoC: codecs: wcd938x: fix resource leaks on component remove
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+commit a3406f87775fee986876e03f93a84385f54d5999 upstream.
+
+Make sure to release allocated resources on component probe failure and
+on remove.
+
+This is specifically needed to allow probe deferrals of the sound card
+which otherwise fails when reprobing the codec component:
+
+    snd-sc8280xp sound: ASoC: failed to instantiate card -517
+    genirq: Flags mismatch irq 289. 00002001 (HPHR PDM WD INT) vs. 00002001 (HPHR PDM WD INT)
+    wcd938x_codec audio-codec: Failed to request HPHR WD interrupt (-16)
+    genirq: Flags mismatch irq 290. 00002001 (HPHL PDM WD INT) vs. 00002001 (HPHL PDM WD INT)
+    wcd938x_codec audio-codec: Failed to request HPHL WD interrupt (-16)
+    genirq: Flags mismatch irq 291. 00002001 (AUX PDM WD INT) vs. 00002001 (AUX PDM WD INT)
+    wcd938x_codec audio-codec: Failed to request Aux WD interrupt (-16)
+    genirq: Flags mismatch irq 292. 00002001 (mbhc sw intr) vs. 00002001 (mbhc sw intr)
+    wcd938x_codec audio-codec: Failed to request mbhc interrupts -16
+
+Fixes: 8d78602aa87a ("ASoC: codecs: wcd938x: add basic driver")
+Cc: stable@vger.kernel.org     # 5.14
+Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20230705123018.30903-5-johan+linaro@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/codecs/wcd938x.c |   55 +++++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 48 insertions(+), 7 deletions(-)
+
+--- a/sound/soc/codecs/wcd938x.c
++++ b/sound/soc/codecs/wcd938x.c
+@@ -2633,6 +2633,14 @@ static int wcd938x_mbhc_init(struct snd_
+       return 0;
+ }
++
++static void wcd938x_mbhc_deinit(struct snd_soc_component *component)
++{
++      struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
++
++      wcd_mbhc_deinit(wcd938x->wcd_mbhc);
++}
++
+ /* END MBHC */
+ static const struct snd_kcontrol_new wcd938x_snd_controls[] = {
+@@ -3113,20 +3121,26 @@ static int wcd938x_soc_codec_probe(struc
+       ret = request_threaded_irq(wcd938x->hphr_pdm_wd_int, NULL, wcd938x_wd_handle_irq,
+                                  IRQF_ONESHOT | IRQF_TRIGGER_RISING,
+                                  "HPHR PDM WD INT", wcd938x);
+-      if (ret)
++      if (ret) {
+               dev_err(dev, "Failed to request HPHR WD interrupt (%d)\n", ret);
++              goto err_free_clsh_ctrl;
++      }
+       ret = request_threaded_irq(wcd938x->hphl_pdm_wd_int, NULL, wcd938x_wd_handle_irq,
+                                  IRQF_ONESHOT | IRQF_TRIGGER_RISING,
+                                  "HPHL PDM WD INT", wcd938x);
+-      if (ret)
++      if (ret) {
+               dev_err(dev, "Failed to request HPHL WD interrupt (%d)\n", ret);
++              goto err_free_hphr_pdm_wd_int;
++      }
+       ret = request_threaded_irq(wcd938x->aux_pdm_wd_int, NULL, wcd938x_wd_handle_irq,
+                                  IRQF_ONESHOT | IRQF_TRIGGER_RISING,
+                                  "AUX PDM WD INT", wcd938x);
+-      if (ret)
++      if (ret) {
+               dev_err(dev, "Failed to request Aux WD interrupt (%d)\n", ret);
++              goto err_free_hphl_pdm_wd_int;
++      }
+       /* Disable watchdog interrupt for HPH and AUX */
+       disable_irq_nosync(wcd938x->hphr_pdm_wd_int);
+@@ -3141,7 +3155,7 @@ static int wcd938x_soc_codec_probe(struc
+                       dev_err(component->dev,
+                               "%s: Failed to add snd ctrls for variant: %d\n",
+                               __func__, wcd938x->variant);
+-                      goto err;
++                      goto err_free_aux_pdm_wd_int;
+               }
+               break;
+       case WCD9385:
+@@ -3151,7 +3165,7 @@ static int wcd938x_soc_codec_probe(struc
+                       dev_err(component->dev,
+                               "%s: Failed to add snd ctrls for variant: %d\n",
+                               __func__, wcd938x->variant);
+-                      goto err;
++                      goto err_free_aux_pdm_wd_int;
+               }
+               break;
+       default:
+@@ -3159,12 +3173,38 @@ static int wcd938x_soc_codec_probe(struc
+       }
+       ret = wcd938x_mbhc_init(component);
+-      if (ret)
++      if (ret) {
+               dev_err(component->dev,  "mbhc initialization failed\n");
+-err:
++              goto err_free_aux_pdm_wd_int;
++      }
++
++      return 0;
++
++err_free_aux_pdm_wd_int:
++      free_irq(wcd938x->aux_pdm_wd_int, wcd938x);
++err_free_hphl_pdm_wd_int:
++      free_irq(wcd938x->hphl_pdm_wd_int, wcd938x);
++err_free_hphr_pdm_wd_int:
++      free_irq(wcd938x->hphr_pdm_wd_int, wcd938x);
++err_free_clsh_ctrl:
++      wcd_clsh_ctrl_free(wcd938x->clsh_info);
++
+       return ret;
+ }
++static void wcd938x_soc_codec_remove(struct snd_soc_component *component)
++{
++      struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
++
++      wcd938x_mbhc_deinit(component);
++
++      free_irq(wcd938x->aux_pdm_wd_int, wcd938x);
++      free_irq(wcd938x->hphl_pdm_wd_int, wcd938x);
++      free_irq(wcd938x->hphr_pdm_wd_int, wcd938x);
++
++      wcd_clsh_ctrl_free(wcd938x->clsh_info);
++}
++
+ static int wcd938x_codec_set_jack(struct snd_soc_component *comp,
+                                 struct snd_soc_jack *jack, void *data)
+ {
+@@ -3181,6 +3221,7 @@ static int wcd938x_codec_set_jack(struct
+ static const struct snd_soc_component_driver soc_codec_dev_wcd938x = {
+       .name = "wcd938x_codec",
+       .probe = wcd938x_soc_codec_probe,
++      .remove = wcd938x_soc_codec_remove,
+       .controls = wcd938x_snd_controls,
+       .num_controls = ARRAY_SIZE(wcd938x_snd_controls),
+       .dapm_widgets = wcd938x_dapm_widgets,
diff --git a/queue-6.4/asoc-codecs-wcd938x-fix-soundwire-initialisation-race.patch b/queue-6.4/asoc-codecs-wcd938x-fix-soundwire-initialisation-race.patch
new file mode 100644 (file)
index 0000000..b36252e
--- /dev/null
@@ -0,0 +1,55 @@
+From 6f49256897083848ce9a59651f6b53fc80462397 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan+linaro@kernel.org>
+Date: Sat, 1 Jul 2023 11:47:23 +0200
+Subject: ASoC: codecs: wcd938x: fix soundwire initialisation race
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+commit 6f49256897083848ce9a59651f6b53fc80462397 upstream.
+
+Make sure that the soundwire device used for register accesses has been
+enumerated and initialised before trying to read the codec variant
+during component probe.
+
+This specifically avoids interpreting (a masked and shifted) -EBUSY
+errno as the variant:
+
+       wcd938x_codec audio-codec: ASoC: error at soc_component_read_no_lock on audio-codec for register: [0x000034b0] -16
+
+in case the soundwire device has not yet been initialised, which in turn
+prevents some headphone controls from being registered.
+
+Fixes: 8d78602aa87a ("ASoC: codecs: wcd938x: add basic driver")
+Cc: stable@vger.kernel.org     # 5.14
+Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Reported-by: Steev Klimaszewski <steev@kali.org>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Tested-by: Steev Klimaszewski <steev@kali.org>
+Link: https://lore.kernel.org/r/20230701094723.29379-1-johan+linaro@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/codecs/wcd938x.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/sound/soc/codecs/wcd938x.c
++++ b/sound/soc/codecs/wcd938x.c
+@@ -3090,9 +3090,18 @@ static int wcd938x_irq_init(struct wcd93
+ static int wcd938x_soc_codec_probe(struct snd_soc_component *component)
+ {
+       struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
++      struct sdw_slave *tx_sdw_dev = wcd938x->tx_sdw_dev;
+       struct device *dev = component->dev;
++      unsigned long time_left;
+       int ret, i;
++      time_left = wait_for_completion_timeout(&tx_sdw_dev->initialization_complete,
++                                              msecs_to_jiffies(2000));
++      if (!time_left) {
++              dev_err(dev, "soundwire device init timeout\n");
++              return -ETIMEDOUT;
++      }
++
+       snd_soc_component_init_regmap(component, wcd938x->regmap);
+       ret = pm_runtime_resume_and_get(dev);
diff --git a/queue-6.4/asoc-cs35l45-select-regmap_irq.patch b/queue-6.4/asoc-cs35l45-select-regmap_irq.patch
new file mode 100644 (file)
index 0000000..160366e
--- /dev/null
@@ -0,0 +1,41 @@
+From d9ba2975e98a4bec0a9f8d4be4c1de8883fccb71 Mon Sep 17 00:00:00 2001
+From: Nathan Chancellor <nathan@kernel.org>
+Date: Mon, 3 Jul 2023 14:43:15 -0700
+Subject: ASoC: cs35l45: Select REGMAP_IRQ
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+commit d9ba2975e98a4bec0a9f8d4be4c1de8883fccb71 upstream.
+
+After commit 6085f9e6dc19 ("ASoC: cs35l45: IRQ support"), without any
+other configuration that selects CONFIG_REGMAP_IRQ, modpost errors out
+with:
+
+  ERROR: modpost: "regmap_irq_get_virq" [sound/soc/codecs/snd-soc-cs35l45.ko] undefined!
+  ERROR: modpost: "devm_regmap_add_irq_chip" [sound/soc/codecs/snd-soc-cs35l45.ko] undefined!
+
+Add the Kconfig selection to ensure these functions get built and
+included, which resolves the build failure.
+
+Cc: stable@vger.kernel.org
+Fixes: 6085f9e6dc19 ("ASoC: cs35l45: IRQ support")
+Reported-by: Marcus Seyfarth <m.seyfarth@gmail.com>
+Closes: https://github.com/ClangBuiltLinux/linux/issues/1882
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Link: https://lore.kernel.org/r/20230703-cs35l45-select-regmap_irq-v1-1-37d7e838b614@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/codecs/Kconfig |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -701,6 +701,7 @@ config SND_SOC_CS35L41_I2C
+ config SND_SOC_CS35L45
+       tristate
++      select REGMAP_IRQ
+ config SND_SOC_CS35L45_SPI
+       tristate "Cirrus Logic CS35L45 CODEC (SPI)"
diff --git a/queue-6.4/asoc-cs42l51-fix-driver-to-properly-autoload-with-automatic-module-loading.patch b/queue-6.4/asoc-cs42l51-fix-driver-to-properly-autoload-with-automatic-module-loading.patch
new file mode 100644 (file)
index 0000000..6729b14
--- /dev/null
@@ -0,0 +1,86 @@
+From e51df4f81b02bcdd828a04de7c1eb6a92988b61e Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
+Date: Thu, 13 Jul 2023 13:21:12 +0200
+Subject: ASoC: cs42l51: fix driver to properly autoload with automatic module loading
+
+From: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
+
+commit e51df4f81b02bcdd828a04de7c1eb6a92988b61e upstream.
+
+In commit 2cb1e0259f50 ("ASoC: cs42l51: re-hook of_match_table
+pointer"), 9 years ago, some random guy fixed the cs42l51 after it was
+split into a core part and an I2C part to properly match based on a
+Device Tree compatible string.
+
+However, the fix in this commit is wrong: the MODULE_DEVICE_TABLE(of,
+....) is in the core part of the driver, not the I2C part. Therefore,
+automatic module loading based on module.alias, based on matching with
+the DT compatible string, loads the core part of the driver, but not
+the I2C part. And threfore, the i2c_driver is not registered, and the
+codec is not known to the system, nor matched with a DT node with the
+corresponding compatible string.
+
+In order to fix that, we move the MODULE_DEVICE_TABLE(of, ...) into
+the I2C part of the driver. The cs42l51_of_match[] array is also moved
+as well, as it is not possible to have this definition in one file,
+and the MODULE_DEVICE_TABLE(of, ...) invocation in another file, due
+to how MODULE_DEVICE_TABLE works.
+
+Thanks to this commit, the I2C part of the driver now properly
+autoloads, and thanks to its dependency on the core part, the core
+part gets autoloaded as well, resulting in a functional sound card
+without having to manually load kernel modules.
+
+Fixes: 2cb1e0259f50 ("ASoC: cs42l51: re-hook of_match_table pointer")
+Cc: stable@vger.kernel.org
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
+Link: https://lore.kernel.org/r/20230713112112.778576-1-thomas.petazzoni@bootlin.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/codecs/cs42l51-i2c.c |    6 ++++++
+ sound/soc/codecs/cs42l51.c     |    7 -------
+ sound/soc/codecs/cs42l51.h     |    1 -
+ 3 files changed, 6 insertions(+), 8 deletions(-)
+
+--- a/sound/soc/codecs/cs42l51-i2c.c
++++ b/sound/soc/codecs/cs42l51-i2c.c
+@@ -19,6 +19,12 @@ static struct i2c_device_id cs42l51_i2c_
+ };
+ MODULE_DEVICE_TABLE(i2c, cs42l51_i2c_id);
++const struct of_device_id cs42l51_of_match[] = {
++      { .compatible = "cirrus,cs42l51", },
++      { }
++};
++MODULE_DEVICE_TABLE(of, cs42l51_of_match);
++
+ static int cs42l51_i2c_probe(struct i2c_client *i2c)
+ {
+       struct regmap_config config;
+--- a/sound/soc/codecs/cs42l51.c
++++ b/sound/soc/codecs/cs42l51.c
+@@ -826,13 +826,6 @@ int __maybe_unused cs42l51_resume(struct
+ }
+ EXPORT_SYMBOL_GPL(cs42l51_resume);
+-const struct of_device_id cs42l51_of_match[] = {
+-      { .compatible = "cirrus,cs42l51", },
+-      { }
+-};
+-MODULE_DEVICE_TABLE(of, cs42l51_of_match);
+-EXPORT_SYMBOL_GPL(cs42l51_of_match);
+-
+ MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+ MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver");
+ MODULE_LICENSE("GPL");
+--- a/sound/soc/codecs/cs42l51.h
++++ b/sound/soc/codecs/cs42l51.h
+@@ -16,7 +16,6 @@ int cs42l51_probe(struct device *dev, st
+ void cs42l51_remove(struct device *dev);
+ int __maybe_unused cs42l51_suspend(struct device *dev);
+ int __maybe_unused cs42l51_resume(struct device *dev);
+-extern const struct of_device_id cs42l51_of_match[];
+ #define CS42L51_CHIP_ID                       0x1B
+ #define CS42L51_CHIP_REV_A            0x00
diff --git a/queue-6.4/asoc-fsl_sai-disable-bit-clock-with-transmitter.patch b/queue-6.4/asoc-fsl_sai-disable-bit-clock-with-transmitter.patch
new file mode 100644 (file)
index 0000000..6e550a4
--- /dev/null
@@ -0,0 +1,43 @@
+From 269f399dc19f0e5c51711c3ba3bd06e0ef6ef403 Mon Sep 17 00:00:00 2001
+From: Matus Gajdos <matuszpd@gmail.com>
+Date: Wed, 12 Jul 2023 14:49:33 +0200
+Subject: ASoC: fsl_sai: Disable bit clock with transmitter
+
+From: Matus Gajdos <matuszpd@gmail.com>
+
+commit 269f399dc19f0e5c51711c3ba3bd06e0ef6ef403 upstream.
+
+Otherwise bit clock remains running writing invalid data to the DAC.
+
+Signed-off-by: Matus Gajdos <matuszpd@gmail.com>
+Acked-by: Shengjiu Wang <shengjiu.wang@gmail.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20230712124934.32232-1-matuszpd@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/fsl/fsl_sai.c |    2 +-
+ sound/soc/fsl/fsl_sai.h |    1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+--- a/sound/soc/fsl/fsl_sai.c
++++ b/sound/soc/fsl/fsl_sai.c
+@@ -719,7 +719,7 @@ static void fsl_sai_config_disable(struc
+       u32 xcsr, count = 100;
+       regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
+-                         FSL_SAI_CSR_TERE, 0);
++                         FSL_SAI_CSR_TERE | FSL_SAI_CSR_BCE, 0);
+       /* TERE will remain set till the end of current frame */
+       do {
+--- a/sound/soc/fsl/fsl_sai.h
++++ b/sound/soc/fsl/fsl_sai.h
+@@ -91,6 +91,7 @@
+ /* SAI Transmit/Receive Control Register */
+ #define FSL_SAI_CSR_TERE      BIT(31)
+ #define FSL_SAI_CSR_SE                BIT(30)
++#define FSL_SAI_CSR_BCE               BIT(28)
+ #define FSL_SAI_CSR_FR                BIT(25)
+ #define FSL_SAI_CSR_SR                BIT(24)
+ #define FSL_SAI_CSR_xF_SHIFT  16
diff --git a/queue-6.4/asoc-fsl_sai-revert-asoc-fsl_sai-enable-mctl_mclk_en-bit-for-master-mode.patch b/queue-6.4/asoc-fsl_sai-revert-asoc-fsl_sai-enable-mctl_mclk_en-bit-for-master-mode.patch
new file mode 100644 (file)
index 0000000..63bc909
--- /dev/null
@@ -0,0 +1,53 @@
+From 86867aca7330e4fbcfa2a117e20b48bbb6c758a9 Mon Sep 17 00:00:00 2001
+From: Fabio Estevam <festevam@denx.de>
+Date: Thu, 6 Jul 2023 19:18:27 -0300
+Subject: ASoC: fsl_sai: Revert "ASoC: fsl_sai: Enable MCTL_MCLK_EN bit for master mode"
+
+From: Fabio Estevam <festevam@denx.de>
+
+commit 86867aca7330e4fbcfa2a117e20b48bbb6c758a9 upstream.
+
+This reverts commit ff87d619ac180444db297f043962a5c325ded47b.
+
+Andreas reports that on an i.MX8MP-based system where MCLK needs to be
+used as an input, the MCLK pin is actually an output, despite not having
+the 'fsl,sai-mclk-direction-output' property present in the devicetree.
+
+This is caused by commit ff87d619ac18 ("ASoC: fsl_sai: Enable
+MCTL_MCLK_EN bit for master mode") that sets FSL_SAI_MCTL_MCLK_EN
+unconditionally for imx8mm/8mn/8mp/93, causing the MCLK to always
+be configured as output.
+
+FSL_SAI_MCTL_MCLK_EN corresponds to the MOE (MCLK Output Enable) bit
+of register MCR and the drivers sets it when the
+'fsl,sai-mclk-direction-output' devicetree property is present.
+
+Revert the commit to allow SAI to use MCLK as input as well.
+
+Cc: stable@vger.kernel.org
+Fixes: ff87d619ac18 ("ASoC: fsl_sai: Enable MCTL_MCLK_EN bit for master mode")
+Reported-by: Andreas Henriksson <andreas@fatal.se>
+Signed-off-by: Fabio Estevam <festevam@denx.de>
+Acked-by: Shengjiu Wang <shengjiu.wang@gmail.com>
+Link: https://lore.kernel.org/r/20230706221827.1938990-1-festevam@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/fsl/fsl_sai.c |    6 ------
+ 1 file changed, 6 deletions(-)
+
+--- a/sound/soc/fsl/fsl_sai.c
++++ b/sound/soc/fsl/fsl_sai.c
+@@ -507,12 +507,6 @@ static int fsl_sai_set_bclk(struct snd_s
+                                  savediv / 2 - 1);
+       }
+-      if (sai->soc_data->max_register >= FSL_SAI_MCTL) {
+-              /* SAI is in master mode at this point, so enable MCLK */
+-              regmap_update_bits(sai->regmap, FSL_SAI_MCTL,
+-                                 FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN);
+-      }
+-
+       return 0;
+ }
diff --git a/queue-6.4/asoc-qdsp6-audioreach-fix-topology-probe-deferral.patch b/queue-6.4/asoc-qdsp6-audioreach-fix-topology-probe-deferral.patch
new file mode 100644 (file)
index 0000000..8ccedcb
--- /dev/null
@@ -0,0 +1,37 @@
+From 46ec420573cefa1fc98025e7e6841bdafd6f1e20 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan+linaro@kernel.org>
+Date: Wed, 5 Jul 2023 14:30:12 +0200
+Subject: ASoC: qdsp6: audioreach: fix topology probe deferral
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+commit 46ec420573cefa1fc98025e7e6841bdafd6f1e20 upstream.
+
+Propagate errors when failing to load the topology component so that
+probe deferrals can be handled.
+
+Fixes: 36ad9bf1d93d ("ASoC: qdsp6: audioreach: add topology support")
+Cc: stable@vger.kernel.org      # 5.17
+Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20230705123018.30903-3-johan+linaro@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/soc/qcom/qdsp6/topology.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/sound/soc/qcom/qdsp6/topology.c
++++ b/sound/soc/qcom/qdsp6/topology.c
+@@ -1277,8 +1277,8 @@ int audioreach_tplg_init(struct snd_soc_
+       ret = snd_soc_tplg_component_load(component, &audioreach_tplg_ops, fw);
+       if (ret < 0) {
+-              dev_err(dev, "tplg component load failed%d\n", ret);
+-              ret = -EINVAL;
++              if (ret != -EPROBE_DEFER)
++                      dev_err(dev, "tplg component load failed: %d\n", ret);
+       }
+       release_firmware(fw);
diff --git a/queue-6.4/asoc-rt5640-fix-sleep-in-atomic-context.patch b/queue-6.4/asoc-rt5640-fix-sleep-in-atomic-context.patch
new file mode 100644 (file)
index 0000000..6098e4e
--- /dev/null
@@ -0,0 +1,65 @@
+From 70a6404ff610aa4889d98977da131c37f9ff9d1f Mon Sep 17 00:00:00 2001
+From: Sameer Pujar <spujar@nvidia.com>
+Date: Thu, 29 Jun 2023 10:42:15 +0530
+Subject: ASoC: rt5640: Fix sleep in atomic context
+
+From: Sameer Pujar <spujar@nvidia.com>
+
+commit 70a6404ff610aa4889d98977da131c37f9ff9d1f upstream.
+
+Following prints are observed while testing audio on Jetson AGX Orin which
+has onboard RT5640 audio codec:
+
+  BUG: sleeping function called from invalid context at kernel/workqueue.c:3027
+  in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: 0, name: swapper/0
+  preempt_count: 10001, expected: 0
+  RCU nest depth: 0, expected: 0
+  ------------[ cut here ]------------
+  WARNING: CPU: 0 PID: 0 at kernel/irq/handle.c:159 __handle_irq_event_percpu+0x1e0/0x270
+  ---[ end trace ad1c64905aac14a6 ]-
+
+The IRQ handler rt5640_irq() runs in interrupt context and can sleep
+during cancel_delayed_work_sync().
+
+Fix this by running IRQ handler, rt5640_irq(), in thread context.
+Hence replace request_irq() calls with devm_request_threaded_irq().
+
+Fixes: 051dade34695 ("ASoC: rt5640: Fix the wrong state of JD1 and JD2")
+Cc: stable@vger.kernel.org
+Cc: Oder Chiou <oder_chiou@realtek.com>
+Signed-off-by: Sameer Pujar <spujar@nvidia.com>
+Link: https://lore.kernel.org/r/1688015537-31682-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/codecs/rt5640.c |   12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/sound/soc/codecs/rt5640.c
++++ b/sound/soc/codecs/rt5640.c
+@@ -2567,9 +2567,10 @@ static void rt5640_enable_jack_detect(st
+       if (jack_data && jack_data->use_platform_clock)
+               rt5640->use_platform_clock = jack_data->use_platform_clock;
+-      ret = request_irq(rt5640->irq, rt5640_irq,
+-                        IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+-                        "rt5640", rt5640);
++      ret = devm_request_threaded_irq(component->dev, rt5640->irq,
++                                      NULL, rt5640_irq,
++                                      IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
++                                      "rt5640", rt5640);
+       if (ret) {
+               dev_warn(component->dev, "Failed to reguest IRQ %d: %d\n", rt5640->irq, ret);
+               rt5640_disable_jack_detect(component);
+@@ -2622,8 +2623,9 @@ static void rt5640_enable_hda_jack_detec
+       rt5640->jack = jack;
+-      ret = request_irq(rt5640->irq, rt5640_irq,
+-                        IRQF_TRIGGER_RISING | IRQF_ONESHOT, "rt5640", rt5640);
++      ret = devm_request_threaded_irq(component->dev, rt5640->irq,
++                                      NULL, rt5640_irq, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
++                                      "rt5640", rt5640);
+       if (ret) {
+               dev_warn(component->dev, "Failed to reguest IRQ %d: %d\n", rt5640->irq, ret);
+               rt5640->irq = -ENXIO;
diff --git a/queue-6.4/asoc-tegra-fix-adx-byte-map.patch b/queue-6.4/asoc-tegra-fix-adx-byte-map.patch
new file mode 100644 (file)
index 0000000..a047668
--- /dev/null
@@ -0,0 +1,119 @@
+From 6dfe70be0b0dec0f9297811501bec26c05fd96ad Mon Sep 17 00:00:00 2001
+From: Sheetal <sheetal@nvidia.com>
+Date: Thu, 29 Jun 2023 10:42:14 +0530
+Subject: ASoC: tegra: Fix ADX byte map
+
+From: Sheetal <sheetal@nvidia.com>
+
+commit 6dfe70be0b0dec0f9297811501bec26c05fd96ad upstream.
+
+Byte mask for channel-1 of stream-1 is not getting enabled and this
+causes failures during ADX use cases. This happens because the byte
+map value 0 matches the byte map array and put() callback returns
+without enabling the corresponding bits in the byte mask.
+
+ADX supports 4 output streams and each stream can have a maximum of
+16 channels. Each byte in the input frame is uniquely mapped to a
+byte in one of these 4 outputs. This mapping is done with the help of
+byte map array via user space control setting. The byte map array
+size in the driver is 16 and each array element is of size 4 bytes.
+This corresponds to 64 byte map values.
+
+Each byte in the byte map array can have any value between 0 to 255
+to enable the corresponding bits in the byte mask. The value 256 is
+used as a way to disable the byte map. However the byte map array
+element cannot store this value. The put() callback disables the byte
+mask for 256 value and byte map value is reset to 0 for this case.
+This causes problems during subsequent runs since put() callback,
+for value of 0, just returns without enabling the byte mask. In short,
+the problem is coming because 0 and 256 control values are stored as
+0 in the byte map array.
+
+Right now fix the put() callback by actually looking at the byte mask
+array state to identify if any change is needed and update the fields
+accordingly. The get() callback needs an update as well to return the
+correct control value that user has set before. Note that when user
+set 256, the value is stored as 0 and byte mask is disabled. So byte
+mask state is used to either return 256 or the value from byte map
+array.
+
+Given above, this looks bit complicated and all this happens because
+the byte map array is tightly packed and cannot actually store the 256
+value. Right now the priority is to fix the existing failure and a TODO
+item is put to improve this logic.
+
+Fixes: 3c97881b8c8a ("ASoC: tegra: Fix kcontrol put callback in ADX")
+Cc: stable@vger.kernel.org
+Signed-off-by: Sheetal <sheetal@nvidia.com>
+Reviewed-by: Mohan Kumar D <mkumard@nvidia.com>
+Reviewed-by: Sameer Pujar <spujar@nvidia.com>
+Link: https://lore.kernel.org/r/1688015537-31682-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_adx.c |   34 ++++++++++++++++++++++------------
+ 1 file changed, 22 insertions(+), 12 deletions(-)
+
+--- a/sound/soc/tegra/tegra210_adx.c
++++ b/sound/soc/tegra/tegra210_adx.c
+@@ -2,7 +2,7 @@
+ //
+ // tegra210_adx.c - Tegra210 ADX driver
+ //
+-// Copyright (c) 2021 NVIDIA CORPORATION.  All rights reserved.
++// Copyright (c) 2021-2023 NVIDIA CORPORATION.  All rights reserved.
+ #include <linux/clk.h>
+ #include <linux/device.h>
+@@ -175,10 +175,20 @@ static int tegra210_adx_get_byte_map(str
+       mc = (struct soc_mixer_control *)kcontrol->private_value;
+       enabled = adx->byte_mask[mc->reg / 32] & (1 << (mc->reg % 32));
++      /*
++       * TODO: Simplify this logic to just return from bytes_map[]
++       *
++       * Presently below is required since bytes_map[] is
++       * tightly packed and cannot store the control value of 256.
++       * Byte mask state is used to know if 256 needs to be returned.
++       * Note that for control value of 256, the put() call stores 0
++       * in the bytes_map[] and disables the corresponding bit in
++       * byte_mask[].
++       */
+       if (enabled)
+               ucontrol->value.integer.value[0] = bytes_map[mc->reg];
+       else
+-              ucontrol->value.integer.value[0] = 0;
++              ucontrol->value.integer.value[0] = 256;
+       return 0;
+ }
+@@ -192,19 +202,19 @@ static int tegra210_adx_put_byte_map(str
+       int value = ucontrol->value.integer.value[0];
+       struct soc_mixer_control *mc =
+               (struct soc_mixer_control *)kcontrol->private_value;
++      unsigned int mask_val = adx->byte_mask[mc->reg / 32];
+-      if (value == bytes_map[mc->reg])
++      if (value >= 0 && value <= 255)
++              mask_val |= (1 << (mc->reg % 32));
++      else
++              mask_val &= ~(1 << (mc->reg % 32));
++
++      if (mask_val == adx->byte_mask[mc->reg / 32])
+               return 0;
+-      if (value >= 0 && value <= 255) {
+-              /* update byte map and enable slot */
+-              bytes_map[mc->reg] = value;
+-              adx->byte_mask[mc->reg / 32] |= (1 << (mc->reg % 32));
+-      } else {
+-              /* reset byte map and disable slot */
+-              bytes_map[mc->reg] = 0;
+-              adx->byte_mask[mc->reg / 32] &= ~(1 << (mc->reg % 32));
+-      }
++      /* Update byte map and slot */
++      bytes_map[mc->reg] = value % 256;
++      adx->byte_mask[mc->reg / 32] = mask_val;
+       return 1;
+ }
diff --git a/queue-6.4/asoc-tegra-fix-amx-byte-map.patch b/queue-6.4/asoc-tegra-fix-amx-byte-map.patch
new file mode 100644 (file)
index 0000000..c707318
--- /dev/null
@@ -0,0 +1,125 @@
+From 49bd7b08149417a30aa7d92c8c85b3518de44a76 Mon Sep 17 00:00:00 2001
+From: Sheetal <sheetal@nvidia.com>
+Date: Thu, 29 Jun 2023 10:42:13 +0530
+Subject: ASoC: tegra: Fix AMX byte map
+
+From: Sheetal <sheetal@nvidia.com>
+
+commit 49bd7b08149417a30aa7d92c8c85b3518de44a76 upstream.
+
+Byte mask for channel-1 of stream-1 is not getting enabled and this
+causes failures during AMX use cases. This happens because the byte
+map value 0 matches the byte map array and put() callback returns
+without enabling the corresponding bits in the byte mask.
+
+AMX supports 4 input streams and each stream can take a maximum of
+16 channels. Each byte in the output frame is uniquely mapped to a
+byte in one of these 4 inputs. This mapping is done with the help of
+byte map array via user space control setting. The byte map array
+size in the driver is 16 and each array element is of size 4 bytes.
+This corresponds to 64 byte map values.
+
+Each byte in the byte map array can have any value between 0 to 255
+to enable the corresponding bits in the byte mask. The value 256 is
+used as a way to disable the byte map. However the byte map array
+element cannot store this value. The put() callback disables the byte
+mask for 256 value and byte map value is reset to 0 for this case.
+This causes problems during subsequent runs since put() callback,
+for value of 0, just returns without enabling the byte mask. In short,
+the problem is coming because 0 and 256 control values are stored as
+0 in the byte map array.
+
+Right now fix the put() callback by actually looking at the byte mask
+array state to identify if any change is needed and update the fields
+accordingly. The get() callback needs an update as well to return the
+correct control value that user has set before. Note that when user
+sets 256, the value is stored as 0 and byte mask is disabled. So byte
+mask state is used to either return 256 or the value from byte map
+array.
+
+Given above, this looks bit complicated and all this happens because
+the byte map array is tightly packed and cannot actually store the 256
+value. Right now the priority is to fix the existing failure and a TODO
+item is put to improve this logic.
+
+Fixes: 8db78ace1ba8 ("ASoC: tegra: Fix kcontrol put callback in AMX")
+Cc: stable@vger.kernel.org
+Signed-off-by: Sheetal <sheetal@nvidia.com>
+Reviewed-by: Mohan Kumar D <mkumard@nvidia.com>
+Reviewed-by: Sameer Pujar <spujar@nvidia.com>
+Link: https://lore.kernel.org/r/1688015537-31682-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_amx.c |   40 ++++++++++++++++++++++------------------
+ 1 file changed, 22 insertions(+), 18 deletions(-)
+
+--- a/sound/soc/tegra/tegra210_amx.c
++++ b/sound/soc/tegra/tegra210_amx.c
+@@ -2,7 +2,7 @@
+ //
+ // tegra210_amx.c - Tegra210 AMX driver
+ //
+-// Copyright (c) 2021 NVIDIA CORPORATION.  All rights reserved.
++// Copyright (c) 2021-2023 NVIDIA CORPORATION.  All rights reserved.
+ #include <linux/clk.h>
+ #include <linux/device.h>
+@@ -203,10 +203,20 @@ static int tegra210_amx_get_byte_map(str
+       else
+               enabled = amx->byte_mask[0] & (1 << reg);
++      /*
++       * TODO: Simplify this logic to just return from bytes_map[]
++       *
++       * Presently below is required since bytes_map[] is
++       * tightly packed and cannot store the control value of 256.
++       * Byte mask state is used to know if 256 needs to be returned.
++       * Note that for control value of 256, the put() call stores 0
++       * in the bytes_map[] and disables the corresponding bit in
++       * byte_mask[].
++       */
+       if (enabled)
+               ucontrol->value.integer.value[0] = bytes_map[reg];
+       else
+-              ucontrol->value.integer.value[0] = 0;
++              ucontrol->value.integer.value[0] = 256;
+       return 0;
+ }
+@@ -221,25 +231,19 @@ static int tegra210_amx_put_byte_map(str
+       unsigned char *bytes_map = (unsigned char *)&amx->map;
+       int reg = mc->reg;
+       int value = ucontrol->value.integer.value[0];
++      unsigned int mask_val = amx->byte_mask[reg / 32];
+-      if (value == bytes_map[reg])
++      if (value >= 0 && value <= 255)
++              mask_val |= (1 << (reg % 32));
++      else
++              mask_val &= ~(1 << (reg % 32));
++
++      if (mask_val == amx->byte_mask[reg / 32])
+               return 0;
+-      if (value >= 0 && value <= 255) {
+-              /* Update byte map and enable slot */
+-              bytes_map[reg] = value;
+-              if (reg > 31)
+-                      amx->byte_mask[1] |= (1 << (reg - 32));
+-              else
+-                      amx->byte_mask[0] |= (1 << reg);
+-      } else {
+-              /* Reset byte map and disable slot */
+-              bytes_map[reg] = 0;
+-              if (reg > 31)
+-                      amx->byte_mask[1] &= ~(1 << (reg - 32));
+-              else
+-                      amx->byte_mask[0] &= ~(1 << reg);
+-      }
++      /* Update byte map and slot */
++      bytes_map[reg] = value % 256;
++      amx->byte_mask[reg / 32] = mask_val;
+       return 1;
+ }
diff --git a/queue-6.4/can-bcm-fix-uaf-in-bcm_proc_show.patch b/queue-6.4/can-bcm-fix-uaf-in-bcm_proc_show.patch
new file mode 100644 (file)
index 0000000..5aad27d
--- /dev/null
@@ -0,0 +1,92 @@
+From 55c3b96074f3f9b0aee19bf93cd71af7516582bb Mon Sep 17 00:00:00 2001
+From: YueHaibing <yuehaibing@huawei.com>
+Date: Sat, 15 Jul 2023 17:25:43 +0800
+Subject: can: bcm: Fix UAF in bcm_proc_show()
+
+From: YueHaibing <yuehaibing@huawei.com>
+
+commit 55c3b96074f3f9b0aee19bf93cd71af7516582bb upstream.
+
+BUG: KASAN: slab-use-after-free in bcm_proc_show+0x969/0xa80
+Read of size 8 at addr ffff888155846230 by task cat/7862
+
+CPU: 1 PID: 7862 Comm: cat Not tainted 6.5.0-rc1-00153-gc8746099c197 #230
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xd5/0x150
+ print_report+0xc1/0x5e0
+ kasan_report+0xba/0xf0
+ bcm_proc_show+0x969/0xa80
+ seq_read_iter+0x4f6/0x1260
+ seq_read+0x165/0x210
+ proc_reg_read+0x227/0x300
+ vfs_read+0x1d5/0x8d0
+ ksys_read+0x11e/0x240
+ do_syscall_64+0x35/0xb0
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+Allocated by task 7846:
+ kasan_save_stack+0x1e/0x40
+ kasan_set_track+0x21/0x30
+ __kasan_kmalloc+0x9e/0xa0
+ bcm_sendmsg+0x264b/0x44e0
+ sock_sendmsg+0xda/0x180
+ ____sys_sendmsg+0x735/0x920
+ ___sys_sendmsg+0x11d/0x1b0
+ __sys_sendmsg+0xfa/0x1d0
+ do_syscall_64+0x35/0xb0
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+Freed by task 7846:
+ kasan_save_stack+0x1e/0x40
+ kasan_set_track+0x21/0x30
+ kasan_save_free_info+0x27/0x40
+ ____kasan_slab_free+0x161/0x1c0
+ slab_free_freelist_hook+0x119/0x220
+ __kmem_cache_free+0xb4/0x2e0
+ rcu_core+0x809/0x1bd0
+
+bcm_op is freed before procfs entry be removed in bcm_release(),
+this lead to bcm_proc_show() may read the freed bcm_op.
+
+Fixes: ffd980f976e7 ("[CAN]: Add broadcast manager (bcm) protocol")
+Signed-off-by: YueHaibing <yuehaibing@huawei.com>
+Reviewed-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Link: https://lore.kernel.org/all/20230715092543.15548-1-yuehaibing@huawei.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/can/bcm.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/net/can/bcm.c
++++ b/net/can/bcm.c
+@@ -1526,6 +1526,12 @@ static int bcm_release(struct socket *so
+       lock_sock(sk);
++#if IS_ENABLED(CONFIG_PROC_FS)
++      /* remove procfs entry */
++      if (net->can.bcmproc_dir && bo->bcm_proc_read)
++              remove_proc_entry(bo->procname, net->can.bcmproc_dir);
++#endif /* CONFIG_PROC_FS */
++
+       list_for_each_entry_safe(op, next, &bo->tx_ops, list)
+               bcm_remove_op(op);
+@@ -1561,12 +1567,6 @@ static int bcm_release(struct socket *so
+       list_for_each_entry_safe(op, next, &bo->rx_ops, list)
+               bcm_remove_op(op);
+-#if IS_ENABLED(CONFIG_PROC_FS)
+-      /* remove procfs entry */
+-      if (net->can.bcmproc_dir && bo->bcm_proc_read)
+-              remove_proc_entry(bo->procname, net->can.bcmproc_dir);
+-#endif /* CONFIG_PROC_FS */
+-
+       /* remove device reference */
+       if (bo->bound) {
+               bo->bound   = 0;
diff --git a/queue-6.4/can-gs_usb-fix-time-stamp-counter-initialization.patch b/queue-6.4/can-gs_usb-fix-time-stamp-counter-initialization.patch
new file mode 100644 (file)
index 0000000..1a0198c
--- /dev/null
@@ -0,0 +1,292 @@
+From 5886e4d5ecec3e22844efed90b2dd383ef804b3a Mon Sep 17 00:00:00 2001
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+Date: Fri, 7 Jul 2023 18:44:23 +0200
+Subject: can: gs_usb: fix time stamp counter initialization
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+commit 5886e4d5ecec3e22844efed90b2dd383ef804b3a upstream.
+
+If the gs_usb device driver is unloaded (or unbound) before the
+interface is shut down, the USB stack first calls the struct
+usb_driver::disconnect and then the struct net_device_ops::ndo_stop
+callback.
+
+In gs_usb_disconnect() all pending bulk URBs are killed, i.e. no more
+RX'ed CAN frames are send from the USB device to the host. Later in
+gs_can_close() a reset control message is send to each CAN channel to
+remove the controller from the CAN bus. In this race window the USB
+device can still receive CAN frames from the bus and internally queue
+them to be send to the host.
+
+At least in the current version of the candlelight firmware, the queue
+of received CAN frames is not emptied during the reset command. After
+loading (or binding) the gs_usb driver, new URBs are submitted during
+the struct net_device_ops::ndo_open callback and the candlelight
+firmware starts sending its already queued CAN frames to the host.
+
+However, this scenario was not considered when implementing the
+hardware timestamp function. The cycle counter/time counter
+infrastructure is set up (gs_usb_timestamp_init()) after the USBs are
+submitted, resulting in a NULL pointer dereference if
+timecounter_cyc2time() (via the call chain:
+gs_usb_receive_bulk_callback() -> gs_usb_set_timestamp() ->
+gs_usb_skb_set_timestamp()) is called too early.
+
+Move the gs_usb_timestamp_init() function before the URBs are
+submitted to fix this problem.
+
+For a comprehensive solution, we need to consider gs_usb devices with
+more than 1 channel. The cycle counter/time counter infrastructure is
+setup per channel, but the RX URBs are per device. Once gs_can_open()
+of _a_ channel has been called, and URBs have been submitted, the
+gs_usb_receive_bulk_callback() can be called for _all_ available
+channels, even for channels that are not running, yet. As cycle
+counter/time counter has not set up, this will again lead to a NULL
+pointer dereference.
+
+Convert the cycle counter/time counter from a "per channel" to a "per
+device" functionality. Also set it up, before submitting any URBs to
+the device.
+
+Further in gs_usb_receive_bulk_callback(), don't process any URBs for
+not started CAN channels, only resubmit the URB.
+
+Fixes: 45dfa45f52e6 ("can: gs_usb: add RX and TX hardware timestamp support")
+Closes: https://github.com/candle-usb/candleLight_fw/issues/137#issuecomment-1623532076
+Cc: stable@vger.kernel.org
+Cc: John Whittington <git@jbrengineering.co.uk>
+Link: https://lore.kernel.org/all/20230716-gs_usb-fix-time-stamp-counter-v1-2-9017cefcd9d5@pengutronix.de
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/usb/gs_usb.c |  101 ++++++++++++++++++++++---------------------
+ 1 file changed, 53 insertions(+), 48 deletions(-)
+
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -303,12 +303,6 @@ struct gs_can {
+       struct can_bittiming_const bt_const, data_bt_const;
+       unsigned int channel;   /* channel number */
+-      /* time counter for hardware timestamps */
+-      struct cyclecounter cc;
+-      struct timecounter tc;
+-      spinlock_t tc_lock; /* spinlock to guard access tc->cycle_last */
+-      struct delayed_work timestamp;
+-
+       u32 feature;
+       unsigned int hf_size_tx;
+@@ -325,6 +319,13 @@ struct gs_usb {
+       struct gs_can *canch[GS_MAX_INTF];
+       struct usb_anchor rx_submitted;
+       struct usb_device *udev;
++
++      /* time counter for hardware timestamps */
++      struct cyclecounter cc;
++      struct timecounter tc;
++      spinlock_t tc_lock; /* spinlock to guard access tc->cycle_last */
++      struct delayed_work timestamp;
++
+       unsigned int hf_size_rx;
+       u8 active_channels;
+ };
+@@ -388,15 +389,15 @@ static int gs_cmd_reset(struct gs_can *d
+                                   GFP_KERNEL);
+ }
+-static inline int gs_usb_get_timestamp(const struct gs_can *dev,
++static inline int gs_usb_get_timestamp(const struct gs_usb *parent,
+                                      u32 *timestamp_p)
+ {
+       __le32 timestamp;
+       int rc;
+-      rc = usb_control_msg_recv(dev->udev, 0, GS_USB_BREQ_TIMESTAMP,
++      rc = usb_control_msg_recv(parent->udev, 0, GS_USB_BREQ_TIMESTAMP,
+                                 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+-                                dev->channel, 0,
++                                0, 0,
+                                 &timestamp, sizeof(timestamp),
+                                 USB_CTRL_GET_TIMEOUT,
+                                 GFP_KERNEL);
+@@ -410,20 +411,20 @@ static inline int gs_usb_get_timestamp(c
+ static u64 gs_usb_timestamp_read(const struct cyclecounter *cc) __must_hold(&dev->tc_lock)
+ {
+-      struct gs_can *dev = container_of(cc, struct gs_can, cc);
++      struct gs_usb *parent = container_of(cc, struct gs_usb, cc);
+       u32 timestamp = 0;
+       int err;
+-      lockdep_assert_held(&dev->tc_lock);
++      lockdep_assert_held(&parent->tc_lock);
+       /* drop lock for synchronous USB transfer */
+-      spin_unlock_bh(&dev->tc_lock);
+-      err = gs_usb_get_timestamp(dev, &timestamp);
+-      spin_lock_bh(&dev->tc_lock);
++      spin_unlock_bh(&parent->tc_lock);
++      err = gs_usb_get_timestamp(parent, &timestamp);
++      spin_lock_bh(&parent->tc_lock);
+       if (err)
+-              netdev_err(dev->netdev,
+-                         "Error %d while reading timestamp. HW timestamps may be inaccurate.",
+-                         err);
++              dev_err(&parent->udev->dev,
++                      "Error %d while reading timestamp. HW timestamps may be inaccurate.",
++                      err);
+       return timestamp;
+ }
+@@ -431,14 +432,14 @@ static u64 gs_usb_timestamp_read(const s
+ static void gs_usb_timestamp_work(struct work_struct *work)
+ {
+       struct delayed_work *delayed_work = to_delayed_work(work);
+-      struct gs_can *dev;
++      struct gs_usb *parent;
+-      dev = container_of(delayed_work, struct gs_can, timestamp);
+-      spin_lock_bh(&dev->tc_lock);
+-      timecounter_read(&dev->tc);
+-      spin_unlock_bh(&dev->tc_lock);
++      parent = container_of(delayed_work, struct gs_usb, timestamp);
++      spin_lock_bh(&parent->tc_lock);
++      timecounter_read(&parent->tc);
++      spin_unlock_bh(&parent->tc_lock);
+-      schedule_delayed_work(&dev->timestamp,
++      schedule_delayed_work(&parent->timestamp,
+                             GS_USB_TIMESTAMP_WORK_DELAY_SEC * HZ);
+ }
+@@ -446,37 +447,38 @@ static void gs_usb_skb_set_timestamp(str
+                                    struct sk_buff *skb, u32 timestamp)
+ {
+       struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb);
++      struct gs_usb *parent = dev->parent;
+       u64 ns;
+-      spin_lock_bh(&dev->tc_lock);
+-      ns = timecounter_cyc2time(&dev->tc, timestamp);
+-      spin_unlock_bh(&dev->tc_lock);
++      spin_lock_bh(&parent->tc_lock);
++      ns = timecounter_cyc2time(&parent->tc, timestamp);
++      spin_unlock_bh(&parent->tc_lock);
+       hwtstamps->hwtstamp = ns_to_ktime(ns);
+ }
+-static void gs_usb_timestamp_init(struct gs_can *dev)
++static void gs_usb_timestamp_init(struct gs_usb *parent)
+ {
+-      struct cyclecounter *cc = &dev->cc;
++      struct cyclecounter *cc = &parent->cc;
+       cc->read = gs_usb_timestamp_read;
+       cc->mask = CYCLECOUNTER_MASK(32);
+       cc->shift = 32 - bits_per(NSEC_PER_SEC / GS_USB_TIMESTAMP_TIMER_HZ);
+       cc->mult = clocksource_hz2mult(GS_USB_TIMESTAMP_TIMER_HZ, cc->shift);
+-      spin_lock_init(&dev->tc_lock);
+-      spin_lock_bh(&dev->tc_lock);
+-      timecounter_init(&dev->tc, &dev->cc, ktime_get_real_ns());
+-      spin_unlock_bh(&dev->tc_lock);
++      spin_lock_init(&parent->tc_lock);
++      spin_lock_bh(&parent->tc_lock);
++      timecounter_init(&parent->tc, &parent->cc, ktime_get_real_ns());
++      spin_unlock_bh(&parent->tc_lock);
+-      INIT_DELAYED_WORK(&dev->timestamp, gs_usb_timestamp_work);
+-      schedule_delayed_work(&dev->timestamp,
++      INIT_DELAYED_WORK(&parent->timestamp, gs_usb_timestamp_work);
++      schedule_delayed_work(&parent->timestamp,
+                             GS_USB_TIMESTAMP_WORK_DELAY_SEC * HZ);
+ }
+-static void gs_usb_timestamp_stop(struct gs_can *dev)
++static void gs_usb_timestamp_stop(struct gs_usb *parent)
+ {
+-      cancel_delayed_work_sync(&dev->timestamp);
++      cancel_delayed_work_sync(&parent->timestamp);
+ }
+ static void gs_update_state(struct gs_can *dev, struct can_frame *cf)
+@@ -560,6 +562,9 @@ static void gs_usb_receive_bulk_callback
+       if (!netif_device_present(netdev))
+               return;
++      if (!netif_running(netdev))
++              goto resubmit_urb;
++
+       if (hf->echo_id == -1) { /* normal rx */
+               if (hf->flags & GS_CAN_FLAG_FD) {
+                       skb = alloc_canfd_skb(dev->netdev, &cfd);
+@@ -856,6 +861,9 @@ static int gs_can_open(struct net_device
+       }
+       if (!parent->active_channels) {
++              if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
++                      gs_usb_timestamp_init(parent);
++
+               for (i = 0; i < GS_MAX_RX_URBS; i++) {
+                       u8 *buf;
+@@ -926,13 +934,9 @@ static int gs_can_open(struct net_device
+               flags |= GS_CAN_MODE_FD;
+       /* if hardware supports timestamps, enable it */
+-      if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) {
++      if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
+               flags |= GS_CAN_MODE_HW_TIMESTAMP;
+-              /* start polling timestamp */
+-              gs_usb_timestamp_init(dev);
+-      }
+-
+       /* finally start device */
+       dev->can.state = CAN_STATE_ERROR_ACTIVE;
+       dm.flags = cpu_to_le32(flags);
+@@ -942,8 +946,6 @@ static int gs_can_open(struct net_device
+                                 GFP_KERNEL);
+       if (rc) {
+               netdev_err(netdev, "Couldn't start device (err=%d)\n", rc);
+-              if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
+-                      gs_usb_timestamp_stop(dev);
+               dev->can.state = CAN_STATE_STOPPED;
+               goto out_usb_kill_anchored_urbs;
+@@ -960,9 +962,13 @@ out_usb_unanchor_urb:
+ out_usb_free_urb:
+       usb_free_urb(urb);
+ out_usb_kill_anchored_urbs:
+-      if (!parent->active_channels)
++      if (!parent->active_channels) {
+               usb_kill_anchored_urbs(&dev->tx_submitted);
++              if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
++                      gs_usb_timestamp_stop(parent);
++      }
++
+       close_candev(netdev);
+       return rc;
+@@ -1011,14 +1017,13 @@ static int gs_can_close(struct net_devic
+       netif_stop_queue(netdev);
+-      /* stop polling timestamp */
+-      if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
+-              gs_usb_timestamp_stop(dev);
+-
+       /* Stop polling */
+       parent->active_channels--;
+       if (!parent->active_channels) {
+               usb_kill_anchored_urbs(&parent->rx_submitted);
++
++              if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
++                      gs_usb_timestamp_stop(parent);
+       }
+       /* Stop sending URBs */
diff --git a/queue-6.4/can-gs_usb-gs_can_open-improve-error-handling.patch b/queue-6.4/can-gs_usb-gs_can_open-improve-error-handling.patch
new file mode 100644 (file)
index 0000000..0deda17
--- /dev/null
@@ -0,0 +1,117 @@
+From 2603be9e8167ddc7bea95dcfab9ffc33414215aa Mon Sep 17 00:00:00 2001
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+Date: Fri, 7 Jul 2023 13:43:10 +0200
+Subject: can: gs_usb: gs_can_open(): improve error handling
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+commit 2603be9e8167ddc7bea95dcfab9ffc33414215aa upstream.
+
+The gs_usb driver handles USB devices with more than 1 CAN channel.
+The RX path for all channels share the same bulk endpoint (the
+transmitted bulk data encodes the channel number). These per-device
+resources are allocated and submitted by the first opened channel.
+
+During this allocation, the resources are either released immediately
+in case of a failure or the URBs are anchored. All anchored URBs are
+finally killed with gs_usb_disconnect().
+
+Currently, gs_can_open() returns with an error if the allocation of a
+URB or a buffer fails. However, if usb_submit_urb() fails, the driver
+continues with the URBs submitted so far, even if no URBs were
+successfully submitted.
+
+Treat every error as fatal and free all allocated resources
+immediately.
+
+Switch to goto-style error handling, to prepare the driver for more
+per-device resource allocation.
+
+Cc: stable@vger.kernel.org
+Cc: John Whittington <git@jbrengineering.co.uk>
+Link: https://lore.kernel.org/all/20230716-gs_usb-fix-time-stamp-counter-v1-1-9017cefcd9d5@pengutronix.de
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/usb/gs_usb.c |   31 ++++++++++++++++++++++---------
+ 1 file changed, 22 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -833,6 +833,7 @@ static int gs_can_open(struct net_device
+               .mode = cpu_to_le32(GS_CAN_MODE_START),
+       };
+       struct gs_host_frame *hf;
++      struct urb *urb = NULL;
+       u32 ctrlmode;
+       u32 flags = 0;
+       int rc, i;
+@@ -856,13 +857,14 @@ static int gs_can_open(struct net_device
+       if (!parent->active_channels) {
+               for (i = 0; i < GS_MAX_RX_URBS; i++) {
+-                      struct urb *urb;
+                       u8 *buf;
+                       /* alloc rx urb */
+                       urb = usb_alloc_urb(0, GFP_KERNEL);
+-                      if (!urb)
+-                              return -ENOMEM;
++                      if (!urb) {
++                              rc = -ENOMEM;
++                              goto out_usb_kill_anchored_urbs;
++                      }
+                       /* alloc rx buffer */
+                       buf = kmalloc(dev->parent->hf_size_rx,
+@@ -870,8 +872,8 @@ static int gs_can_open(struct net_device
+                       if (!buf) {
+                               netdev_err(netdev,
+                                          "No memory left for USB buffer\n");
+-                              usb_free_urb(urb);
+-                              return -ENOMEM;
++                              rc = -ENOMEM;
++                              goto out_usb_free_urb;
+                       }
+                       /* fill, anchor, and submit rx urb */
+@@ -894,9 +896,7 @@ static int gs_can_open(struct net_device
+                               netdev_err(netdev,
+                                          "usb_submit failed (err=%d)\n", rc);
+-                              usb_unanchor_urb(urb);
+-                              usb_free_urb(urb);
+-                              break;
++                              goto out_usb_unanchor_urb;
+                       }
+                       /* Drop reference,
+@@ -945,7 +945,8 @@ static int gs_can_open(struct net_device
+               if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP)
+                       gs_usb_timestamp_stop(dev);
+               dev->can.state = CAN_STATE_STOPPED;
+-              return rc;
++
++              goto out_usb_kill_anchored_urbs;
+       }
+       parent->active_channels++;
+@@ -953,6 +954,18 @@ static int gs_can_open(struct net_device
+               netif_start_queue(netdev);
+       return 0;
++
++out_usb_unanchor_urb:
++      usb_unanchor_urb(urb);
++out_usb_free_urb:
++      usb_free_urb(urb);
++out_usb_kill_anchored_urbs:
++      if (!parent->active_channels)
++              usb_kill_anchored_urbs(&dev->tx_submitted);
++
++      close_candev(netdev);
++
++      return rc;
+ }
+ static int gs_usb_get_state(const struct net_device *netdev,
diff --git a/queue-6.4/can-mcp251xfd-__mcp251xfd_chip_set_mode-increase-poll-timeout.patch b/queue-6.4/can-mcp251xfd-__mcp251xfd_chip_set_mode-increase-poll-timeout.patch
new file mode 100644 (file)
index 0000000..e554d47
--- /dev/null
@@ -0,0 +1,87 @@
+From 9efa1a5407e81265ea502cab83be4de503decc49 Mon Sep 17 00:00:00 2001
+From: Fedor Ross <fedor.ross@ifm.com>
+Date: Thu, 4 May 2023 21:50:59 +0200
+Subject: can: mcp251xfd: __mcp251xfd_chip_set_mode(): increase poll timeout
+
+From: Fedor Ross <fedor.ross@ifm.com>
+
+commit 9efa1a5407e81265ea502cab83be4de503decc49 upstream.
+
+The mcp251xfd controller needs an idle bus to enter 'Normal CAN 2.0
+mode' or . The maximum length of a CAN frame is 736 bits (64 data
+bytes, CAN-FD, EFF mode, worst case bit stuffing and interframe
+spacing). For low bit rates like 10 kbit/s the arbitrarily chosen
+MCP251XFD_POLL_TIMEOUT_US of 1 ms is too small.
+
+Otherwise during polling for the CAN controller to enter 'Normal CAN
+2.0 mode' the timeout limit is exceeded and the configuration fails
+with:
+
+| $ ip link set dev can1 up type can bitrate 10000
+| [  731.911072] mcp251xfd spi2.1 can1: Controller failed to enter mode CAN 2.0 Mode (6) and stays in Configuration Mode (4) (con=0x068b0760, osc=0x00000468).
+| [  731.927192] mcp251xfd spi2.1 can1: CRC read error at address 0x0e0c (length=4, data=00 00 00 00, CRC=0x0000) retrying.
+| [  731.938101] A link change request failed with some changes committed already. Interface can1 may have been left with an inconsistent configuration, please check.
+| RTNETLINK answers: Connection timed out
+
+Make MCP251XFD_POLL_TIMEOUT_US timeout calculation dynamic. Use
+maximum of 1ms and bit time of 1 full 64 data bytes CAN-FD frame in
+EFF mode, worst case bit stuffing and interframe spacing at the
+current bit rate.
+
+For easier backporting define the macro MCP251XFD_FRAME_LEN_MAX_BITS
+that holds the max frame length in bits, which is 736. This can be
+replaced by can_frame_bits(true, true, true, true, CANFD_MAX_DLEN) in
+a cleanup patch later.
+
+Fixes: 55e5b97f003e8 ("can: mcp25xxfd: add driver for Microchip MCP25xxFD SPI CAN")
+Signed-off-by: Fedor Ross <fedor.ross@ifm.com>
+Signed-off-by: Marek Vasut <marex@denx.de>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/all/20230717-mcp251xfd-fix-increase-poll-timeout-v5-1-06600f34c684@pengutronix.de
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c |   10 ++++++++--
+ drivers/net/can/spi/mcp251xfd/mcp251xfd.h      |    1 +
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
+@@ -227,6 +227,8 @@ static int
+ __mcp251xfd_chip_set_mode(const struct mcp251xfd_priv *priv,
+                         const u8 mode_req, bool nowait)
+ {
++      const struct can_bittiming *bt = &priv->can.bittiming;
++      unsigned long timeout_us = MCP251XFD_POLL_TIMEOUT_US;
+       u32 con = 0, con_reqop, osc = 0;
+       u8 mode;
+       int err;
+@@ -246,12 +248,16 @@ __mcp251xfd_chip_set_mode(const struct m
+       if (mode_req == MCP251XFD_REG_CON_MODE_SLEEP || nowait)
+               return 0;
++      if (bt->bitrate)
++              timeout_us = max_t(unsigned long, timeout_us,
++                                 MCP251XFD_FRAME_LEN_MAX_BITS * USEC_PER_SEC /
++                                 bt->bitrate);
++
+       err = regmap_read_poll_timeout(priv->map_reg, MCP251XFD_REG_CON, con,
+                                      !mcp251xfd_reg_invalid(con) &&
+                                      FIELD_GET(MCP251XFD_REG_CON_OPMOD_MASK,
+                                                con) == mode_req,
+-                                     MCP251XFD_POLL_SLEEP_US,
+-                                     MCP251XFD_POLL_TIMEOUT_US);
++                                     MCP251XFD_POLL_SLEEP_US, timeout_us);
+       if (err != -ETIMEDOUT && err != -EBADMSG)
+               return err;
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
+@@ -387,6 +387,7 @@ static_assert(MCP251XFD_TIMESTAMP_WORK_D
+ #define MCP251XFD_OSC_STAB_TIMEOUT_US (10 * MCP251XFD_OSC_STAB_SLEEP_US)
+ #define MCP251XFD_POLL_SLEEP_US (10)
+ #define MCP251XFD_POLL_TIMEOUT_US (USEC_PER_MSEC)
++#define MCP251XFD_FRAME_LEN_MAX_BITS (736)
+ /* Misc */
+ #define MCP251XFD_NAPI_WEIGHT 32
diff --git a/queue-6.4/can-raw-fix-receiver-memory-leak.patch b/queue-6.4/can-raw-fix-receiver-memory-leak.patch
new file mode 100644 (file)
index 0000000..7096dff
--- /dev/null
@@ -0,0 +1,233 @@
+From ee8b94c8510ce64afe0b87ef548d23e00915fb10 Mon Sep 17 00:00:00 2001
+From: Ziyang Xuan <william.xuanziyang@huawei.com>
+Date: Tue, 11 Jul 2023 09:17:37 +0800
+Subject: can: raw: fix receiver memory leak
+
+From: Ziyang Xuan <william.xuanziyang@huawei.com>
+
+commit ee8b94c8510ce64afe0b87ef548d23e00915fb10 upstream.
+
+Got kmemleak errors with the following ltp can_filter testcase:
+
+for ((i=1; i<=100; i++))
+do
+        ./can_filter &
+        sleep 0.1
+done
+
+==============================================================
+[<00000000db4a4943>] can_rx_register+0x147/0x360 [can]
+[<00000000a289549d>] raw_setsockopt+0x5ef/0x853 [can_raw]
+[<000000006d3d9ebd>] __sys_setsockopt+0x173/0x2c0
+[<00000000407dbfec>] __x64_sys_setsockopt+0x61/0x70
+[<00000000fd468496>] do_syscall_64+0x33/0x40
+[<00000000b7e47d51>] entry_SYSCALL_64_after_hwframe+0x61/0xc6
+
+It's a bug in the concurrent scenario of unregister_netdevice_many()
+and raw_release() as following:
+
+             cpu0                                        cpu1
+unregister_netdevice_many(can_dev)
+  unlist_netdevice(can_dev) // dev_get_by_index() return NULL after this
+  net_set_todo(can_dev)
+                                               raw_release(can_socket)
+                                                 dev = dev_get_by_index(, ro->ifindex); // dev == NULL
+                                                 if (dev) { // receivers in dev_rcv_lists not free because dev is NULL
+                                                   raw_disable_allfilters(, dev, );
+                                                   dev_put(dev);
+                                                 }
+                                                 ...
+                                                 ro->bound = 0;
+                                                 ...
+
+call_netdevice_notifiers(NETDEV_UNREGISTER, )
+  raw_notify(, NETDEV_UNREGISTER, )
+    if (ro->bound) // invalid because ro->bound has been set 0
+      raw_disable_allfilters(, dev, ); // receivers in dev_rcv_lists will never be freed
+
+Add a net_device pointer member in struct raw_sock to record bound
+can_dev, and use rtnl_lock to serialize raw_socket members between
+raw_bind(), raw_release(), raw_setsockopt() and raw_notify(). Use
+ro->dev to decide whether to free receivers in dev_rcv_lists.
+
+Fixes: 8d0caedb7596 ("can: bcm/raw/isotp: use per module netdevice notifier")
+Reviewed-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Signed-off-by: Ziyang Xuan <william.xuanziyang@huawei.com>
+Link: https://lore.kernel.org/all/20230711011737.1969582-1-william.xuanziyang@huawei.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/can/raw.c |   57 ++++++++++++++++++++++++---------------------------------
+ 1 file changed, 24 insertions(+), 33 deletions(-)
+
+--- a/net/can/raw.c
++++ b/net/can/raw.c
+@@ -84,6 +84,7 @@ struct raw_sock {
+       struct sock sk;
+       int bound;
+       int ifindex;
++      struct net_device *dev;
+       struct list_head notifier;
+       int loopback;
+       int recv_own_msgs;
+@@ -277,7 +278,7 @@ static void raw_notify(struct raw_sock *
+       if (!net_eq(dev_net(dev), sock_net(sk)))
+               return;
+-      if (ro->ifindex != dev->ifindex)
++      if (ro->dev != dev)
+               return;
+       switch (msg) {
+@@ -292,6 +293,7 @@ static void raw_notify(struct raw_sock *
+               ro->ifindex = 0;
+               ro->bound = 0;
++              ro->dev = NULL;
+               ro->count = 0;
+               release_sock(sk);
+@@ -337,6 +339,7 @@ static int raw_init(struct sock *sk)
+       ro->bound            = 0;
+       ro->ifindex          = 0;
++      ro->dev              = NULL;
+       /* set default filter to single entry dfilter */
+       ro->dfilter.can_id   = 0;
+@@ -385,19 +388,13 @@ static int raw_release(struct socket *so
+       lock_sock(sk);
++      rtnl_lock();
+       /* remove current filters & unregister */
+       if (ro->bound) {
+-              if (ro->ifindex) {
+-                      struct net_device *dev;
+-
+-                      dev = dev_get_by_index(sock_net(sk), ro->ifindex);
+-                      if (dev) {
+-                              raw_disable_allfilters(dev_net(dev), dev, sk);
+-                              dev_put(dev);
+-                      }
+-              } else {
++              if (ro->dev)
++                      raw_disable_allfilters(dev_net(ro->dev), ro->dev, sk);
++              else
+                       raw_disable_allfilters(sock_net(sk), NULL, sk);
+-              }
+       }
+       if (ro->count > 1)
+@@ -405,8 +402,10 @@ static int raw_release(struct socket *so
+       ro->ifindex = 0;
+       ro->bound = 0;
++      ro->dev = NULL;
+       ro->count = 0;
+       free_percpu(ro->uniq);
++      rtnl_unlock();
+       sock_orphan(sk);
+       sock->sk = NULL;
+@@ -422,6 +421,7 @@ static int raw_bind(struct socket *sock,
+       struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
+       struct sock *sk = sock->sk;
+       struct raw_sock *ro = raw_sk(sk);
++      struct net_device *dev = NULL;
+       int ifindex;
+       int err = 0;
+       int notify_enetdown = 0;
+@@ -431,14 +431,13 @@ static int raw_bind(struct socket *sock,
+       if (addr->can_family != AF_CAN)
+               return -EINVAL;
++      rtnl_lock();
+       lock_sock(sk);
+       if (ro->bound && addr->can_ifindex == ro->ifindex)
+               goto out;
+       if (addr->can_ifindex) {
+-              struct net_device *dev;
+-
+               dev = dev_get_by_index(sock_net(sk), addr->can_ifindex);
+               if (!dev) {
+                       err = -ENODEV;
+@@ -467,26 +466,20 @@ static int raw_bind(struct socket *sock,
+       if (!err) {
+               if (ro->bound) {
+                       /* unregister old filters */
+-                      if (ro->ifindex) {
+-                              struct net_device *dev;
+-
+-                              dev = dev_get_by_index(sock_net(sk),
+-                                                     ro->ifindex);
+-                              if (dev) {
+-                                      raw_disable_allfilters(dev_net(dev),
+-                                                             dev, sk);
+-                                      dev_put(dev);
+-                              }
+-                      } else {
++                      if (ro->dev)
++                              raw_disable_allfilters(dev_net(ro->dev),
++                                                     ro->dev, sk);
++                      else
+                               raw_disable_allfilters(sock_net(sk), NULL, sk);
+-                      }
+               }
+               ro->ifindex = ifindex;
+               ro->bound = 1;
++              ro->dev = dev;
+       }
+  out:
+       release_sock(sk);
++      rtnl_unlock();
+       if (notify_enetdown) {
+               sk->sk_err = ENETDOWN;
+@@ -553,9 +546,9 @@ static int raw_setsockopt(struct socket
+               rtnl_lock();
+               lock_sock(sk);
+-              if (ro->bound && ro->ifindex) {
+-                      dev = dev_get_by_index(sock_net(sk), ro->ifindex);
+-                      if (!dev) {
++              dev = ro->dev;
++              if (ro->bound && dev) {
++                      if (dev->reg_state != NETREG_REGISTERED) {
+                               if (count > 1)
+                                       kfree(filter);
+                               err = -ENODEV;
+@@ -596,7 +589,6 @@ static int raw_setsockopt(struct socket
+               ro->count  = count;
+  out_fil:
+-              dev_put(dev);
+               release_sock(sk);
+               rtnl_unlock();
+@@ -614,9 +606,9 @@ static int raw_setsockopt(struct socket
+               rtnl_lock();
+               lock_sock(sk);
+-              if (ro->bound && ro->ifindex) {
+-                      dev = dev_get_by_index(sock_net(sk), ro->ifindex);
+-                      if (!dev) {
++              dev = ro->dev;
++              if (ro->bound && dev) {
++                      if (dev->reg_state != NETREG_REGISTERED) {
+                               err = -ENODEV;
+                               goto out_err;
+                       }
+@@ -640,7 +632,6 @@ static int raw_setsockopt(struct socket
+               ro->err_mask = err_mask;
+  out_err:
+-              dev_put(dev);
+               release_sock(sk);
+               rtnl_unlock();
diff --git a/queue-6.4/dma-buf-dma-resv-stop-leaking-on-krealloc-failure.patch b/queue-6.4/dma-buf-dma-resv-stop-leaking-on-krealloc-failure.patch
new file mode 100644 (file)
index 0000000..f19af73
--- /dev/null
@@ -0,0 +1,71 @@
+From 05abb3be91d8788328231ee02973ab3d47f5e3d2 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
+Date: Thu, 13 Jul 2023 22:47:45 +0300
+Subject: dma-buf/dma-resv: Stop leaking on krealloc() failure
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+commit 05abb3be91d8788328231ee02973ab3d47f5e3d2 upstream.
+
+Currently dma_resv_get_fences() will leak the previously
+allocated array if the fence iteration got restarted and
+the krealloc_array() fails.
+
+Free the old array by hand, and make sure we still clear
+the returned *fences so the caller won't end up accessing
+freed memory. Some (but not all) of the callers of
+dma_resv_get_fences() seem to still trawl through the
+array even when dma_resv_get_fences() failed. And let's
+zero out *num_fences as well for good measure.
+
+Cc: Sumit Semwal <sumit.semwal@linaro.org>
+Cc: Christian König <christian.koenig@amd.com>
+Cc: linux-media@vger.kernel.org
+Cc: dri-devel@lists.freedesktop.org
+Cc: linaro-mm-sig@lists.linaro.org
+Fixes: d3c80698c9f5 ("dma-buf: use new iterator in dma_resv_get_fences v3")
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Cc: stable@vger.kernel.org
+Link: https://patchwork.freedesktop.org/patch/msgid/20230713194745.1751-1-ville.syrjala@linux.intel.com
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma-buf/dma-resv.c |   13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/drivers/dma-buf/dma-resv.c
++++ b/drivers/dma-buf/dma-resv.c
+@@ -571,6 +571,7 @@ int dma_resv_get_fences(struct dma_resv
+       dma_resv_for_each_fence_unlocked(&cursor, fence) {
+               if (dma_resv_iter_is_restarted(&cursor)) {
++                      struct dma_fence **new_fences;
+                       unsigned int count;
+                       while (*num_fences)
+@@ -579,13 +580,17 @@ int dma_resv_get_fences(struct dma_resv
+                       count = cursor.num_fences + 1;
+                       /* Eventually re-allocate the array */
+-                      *fences = krealloc_array(*fences, count,
+-                                               sizeof(void *),
+-                                               GFP_KERNEL);
+-                      if (count && !*fences) {
++                      new_fences = krealloc_array(*fences, count,
++                                                  sizeof(void *),
++                                                  GFP_KERNEL);
++                      if (count && !new_fences) {
++                              kfree(*fences);
++                              *fences = NULL;
++                              *num_fences = 0;
+                               dma_resv_iter_end(&cursor);
+                               return -ENOMEM;
+                       }
++                      *fences = new_fences;
+               }
+               (*fences)[(*num_fences)++] = dma_fence_get(fence);
diff --git a/queue-6.4/drm-amd-display-check-tg-is-non-null-before-checking-if-enabled.patch b/queue-6.4/drm-amd-display-check-tg-is-non-null-before-checking-if-enabled.patch
new file mode 100644 (file)
index 0000000..36d7d6b
--- /dev/null
@@ -0,0 +1,38 @@
+From 5a25cefc0920088bb9afafeb80ad3dcd84fe278b Mon Sep 17 00:00:00 2001
+From: Taimur Hassan <syed.hassan@amd.com>
+Date: Tue, 20 Jun 2023 17:00:28 -0400
+Subject: drm/amd/display: check TG is non-null before checking if enabled
+
+From: Taimur Hassan <syed.hassan@amd.com>
+
+commit 5a25cefc0920088bb9afafeb80ad3dcd84fe278b upstream.
+
+[Why & How]
+If there is no TG allocation we can dereference a NULL pointer when
+checking if the TG is enabled.
+
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Acked-by: Alan Liu <haoping.liu@amd.com>
+Signed-off-by: Taimur Hassan <syed.hassan@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+@@ -3309,7 +3309,8 @@ void dcn10_wait_for_mpcc_disconnect(
+               if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst]) {
+                       struct hubp *hubp = get_hubp_by_inst(res_pool, mpcc_inst);
+-                      if (pipe_ctx->stream_res.tg->funcs->is_tg_enabled(pipe_ctx->stream_res.tg))
++                      if (pipe_ctx->stream_res.tg &&
++                              pipe_ctx->stream_res.tg->funcs->is_tg_enabled(pipe_ctx->stream_res.tg))
+                               res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, mpcc_inst);
+                       pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst] = false;
+                       hubp->funcs->set_blank(hubp, true);
diff --git a/queue-6.4/drm-amd-display-disable-mpc-split-by-default-on-special-asic.patch b/queue-6.4/drm-amd-display-disable-mpc-split-by-default-on-special-asic.patch
new file mode 100644 (file)
index 0000000..6b58973
--- /dev/null
@@ -0,0 +1,42 @@
+From a460beefe77d780ac48f19d39333852a7f93ffc1 Mon Sep 17 00:00:00 2001
+From: Zhikai Zhai <zhikai.zhai@amd.com>
+Date: Fri, 30 Jun 2023 11:35:14 +0800
+Subject: drm/amd/display: Disable MPC split by default on special asic
+
+From: Zhikai Zhai <zhikai.zhai@amd.com>
+
+commit a460beefe77d780ac48f19d39333852a7f93ffc1 upstream.
+
+[WHY]
+All of pipes will be used when the MPC split enable on the dcn
+which just has 2 pipes. Then MPO enter will trigger the minimal
+transition which need programe dcn from 2 pipes MPC split to 2
+pipes MPO. This action will cause lag if happen frequently.
+
+[HOW]
+Disable the MPC split for the platform which dcn resource is limited
+
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
+Acked-by: Alan Liu <haoping.liu@amd.com>
+Signed-off-by: Zhikai Zhai <zhikai.zhai@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c
+@@ -65,7 +65,7 @@ static const struct dc_debug_options deb
+               .timing_trace = false,
+               .clock_trace = true,
+               .disable_pplib_clock_request = true,
+-              .pipe_split_policy = MPC_SPLIT_DYNAMIC,
++              .pipe_split_policy = MPC_SPLIT_AVOID,
+               .force_single_disp_pipe_split = false,
+               .disable_dcc = DCC_ENABLE,
+               .vsr_support = true,
diff --git a/queue-6.4/drm-amd-display-keep-phy-active-for-dp-displays-on-dcn31.patch b/queue-6.4/drm-amd-display-keep-phy-active-for-dp-displays-on-dcn31.patch
new file mode 100644 (file)
index 0000000..0f5dc5b
--- /dev/null
@@ -0,0 +1,42 @@
+From 2387ccf43e3c6cb5dbd757c5ef410cca9f14b971 Mon Sep 17 00:00:00 2001
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Date: Thu, 29 Jun 2023 10:35:59 -0400
+Subject: drm/amd/display: Keep PHY active for DP displays on DCN31
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+commit 2387ccf43e3c6cb5dbd757c5ef410cca9f14b971 upstream.
+
+[Why & How]
+Port of a change that went into DCN314 to keep the PHY enabled
+when we have a connected and active DP display.
+
+The PHY can hang if PHY refclk is disabled inadvertently.
+
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Josip Pavic <josip.pavic@amd.com>
+Acked-by: Alan Liu <haoping.liu@amd.com>
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c
+@@ -87,6 +87,11 @@ static int dcn31_get_active_display_cnt_
+                               stream->signal == SIGNAL_TYPE_DVI_SINGLE_LINK ||
+                               stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK)
+                       tmds_present = true;
++
++              /* Checking stream / link detection ensuring that PHY is active*/
++              if (dc_is_dp_signal(stream->signal) && !stream->dpms_off)
++                      display_count++;
++
+       }
+       for (i = 0; i < dc->link_count; i++) {
diff --git a/queue-6.4/drm-amd-display-only-accept-async-flips-for-fast-updates.patch b/queue-6.4/drm-amd-display-only-accept-async-flips-for-fast-updates.patch
new file mode 100644 (file)
index 0000000..f1e0c6a
--- /dev/null
@@ -0,0 +1,82 @@
+From 1ca67aba8d11c2849d395013e1fdce02918d5657 Mon Sep 17 00:00:00 2001
+From: Simon Ser <contact@emersion.fr>
+Date: Wed, 21 Jun 2023 17:24:59 -0300
+Subject: drm/amd/display: only accept async flips for fast updates
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Simon Ser <contact@emersion.fr>
+
+commit 1ca67aba8d11c2849d395013e1fdce02918d5657 upstream.
+
+Up until now, amdgpu was silently degrading to vsync when
+user-space requested an async flip but the hardware didn't support
+it.
+
+The hardware doesn't support immediate flips when the update changes
+the FB pitch, the DCC state, the rotation, enables or disables CRTCs
+or planes, etc. This is reflected in the dm_crtc_state.update_type
+field: UPDATE_TYPE_FAST means that immediate flip is supported.
+
+Silently degrading async flips to vsync is not the expected behavior
+from a uAPI point-of-view. Xorg expects async flips to fail if
+unsupported, to be able to fall back to a blit. i915 already behaves
+this way.
+
+This patch aligns amdgpu with uAPI expectations and returns a failure
+when an async flip is not possible.
+
+Signed-off-by: Simon Ser <contact@emersion.fr>
+Reviewed-by: André Almeida <andrealmeid@igalia.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: André Almeida <andrealmeid@igalia.com>
+Signed-off-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c      |    8 ++++++++
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c |   12 ++++++++++++
+ 2 files changed, 20 insertions(+)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -8055,7 +8055,15 @@ static void amdgpu_dm_commit_planes(stru
+                * Only allow immediate flips for fast updates that don't
+                * change memory domain, FB pitch, DCC state, rotation or
+                * mirroring.
++               *
++               * dm_crtc_helper_atomic_check() only accepts async flips with
++               * fast updates.
+                */
++              if (crtc->state->async_flip &&
++                  acrtc_state->update_type != UPDATE_TYPE_FAST)
++                      drm_warn_once(state->dev,
++                                    "[PLANE:%d:%s] async flip with non-fast update\n",
++                                    plane->base.id, plane->name);
+               bundle->flip_addrs[planes_count].flip_immediate =
+                       crtc->state->async_flip &&
+                       acrtc_state->update_type == UPDATE_TYPE_FAST &&
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+@@ -398,6 +398,18 @@ static int dm_crtc_helper_atomic_check(s
+               return -EINVAL;
+       }
++      /*
++       * Only allow async flips for fast updates that don't change the FB
++       * pitch, the DCC state, rotation, etc.
++       */
++      if (crtc_state->async_flip &&
++          dm_crtc_state->update_type != UPDATE_TYPE_FAST) {
++              drm_dbg_atomic(crtc->dev,
++                             "[CRTC:%d:%s] async flips are only supported for fast updates\n",
++                             crtc->base.id, crtc->name);
++              return -EINVAL;
++      }
++
+       /* In some use cases, like reset, no stream is attached */
+       if (!dm_crtc_state->stream)
+               return 0;
diff --git a/queue-6.4/drm-amdgpu-pm-make-gfxclock-consistent-for-sienna-cichlid.patch b/queue-6.4/drm-amdgpu-pm-make-gfxclock-consistent-for-sienna-cichlid.patch
new file mode 100644 (file)
index 0000000..e03c027
--- /dev/null
@@ -0,0 +1,40 @@
+From a4eb11824170d742531998f4ebd1c6a18b63db47 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Tue, 13 Jun 2023 12:15:38 -0400
+Subject: drm/amdgpu/pm: make gfxclock consistent for sienna cichlid
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit a4eb11824170d742531998f4ebd1c6a18b63db47 upstream.
+
+Use average gfxclock for consistency with other dGPUs.
+
+Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org # 6.1.x
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
+@@ -1927,12 +1927,16 @@ static int sienna_cichlid_read_sensor(st
+               *size = 4;
+               break;
+       case AMDGPU_PP_SENSOR_GFX_MCLK:
+-              ret = sienna_cichlid_get_current_clk_freq_by_table(smu, SMU_UCLK, (uint32_t *)data);
++              ret = sienna_cichlid_get_smu_metrics_data(smu,
++                                                        METRICS_CURR_UCLK,
++                                                        (uint32_t *)data);
+               *(uint32_t *)data *= 100;
+               *size = 4;
+               break;
+       case AMDGPU_PP_SENSOR_GFX_SCLK:
+-              ret = sienna_cichlid_get_current_clk_freq_by_table(smu, SMU_GFXCLK, (uint32_t *)data);
++              ret = sienna_cichlid_get_smu_metrics_data(smu,
++                                                        METRICS_AVERAGE_GFXCLK,
++                                                        (uint32_t *)data);
+               *(uint32_t *)data *= 100;
+               *size = 4;
+               break;
diff --git a/queue-6.4/drm-amdgpu-pm-make-mclk-consistent-for-smu-13.0.7.patch b/queue-6.4/drm-amdgpu-pm-make-mclk-consistent-for-smu-13.0.7.patch
new file mode 100644 (file)
index 0000000..27426d1
--- /dev/null
@@ -0,0 +1,30 @@
+From 068c8bb10f37bb84824625dbbda053a3a3e0d6e1 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Tue, 13 Jun 2023 12:36:17 -0400
+Subject: drm/amdgpu/pm: make mclk consistent for smu 13.0.7
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 068c8bb10f37bb84824625dbbda053a3a3e0d6e1 upstream.
+
+Use current uclk to be consistent with other dGPUs.
+
+Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org # 6.1.x
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+@@ -940,7 +940,7 @@ static int smu_v13_0_7_read_sensor(struc
+               break;
+       case AMDGPU_PP_SENSOR_GFX_MCLK:
+               ret = smu_v13_0_7_get_smu_metrics_data(smu,
+-                                                     METRICS_AVERAGE_UCLK,
++                                                     METRICS_CURR_UCLK,
+                                                      (uint32_t *)data);
+               *(uint32_t *)data *= 100;
+               *size = 4;
diff --git a/queue-6.4/drm-amdgpu-vkms-relax-timer-deactivation-by-hrtimer_try_to_cancel.patch b/queue-6.4/drm-amdgpu-vkms-relax-timer-deactivation-by-hrtimer_try_to_cancel.patch
new file mode 100644 (file)
index 0000000..d26cdf1
--- /dev/null
@@ -0,0 +1,101 @@
+From b42ae87a7b3878afaf4c3852ca66c025a5b996e0 Mon Sep 17 00:00:00 2001
+From: Guchun Chen <guchun.chen@amd.com>
+Date: Thu, 6 Jul 2023 15:57:21 +0800
+Subject: drm/amdgpu/vkms: relax timer deactivation by hrtimer_try_to_cancel
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Guchun Chen <guchun.chen@amd.com>
+
+commit b42ae87a7b3878afaf4c3852ca66c025a5b996e0 upstream.
+
+In below thousands of screen rotation loop tests with virtual display
+enabled, a CPU hard lockup issue may happen, leading system to unresponsive
+and crash.
+
+do {
+       xrandr --output Virtual --rotate inverted
+       xrandr --output Virtual --rotate right
+       xrandr --output Virtual --rotate left
+       xrandr --output Virtual --rotate normal
+} while (1);
+
+NMI watchdog: Watchdog detected hard LOCKUP on cpu 1
+
+? hrtimer_run_softirq+0x140/0x140
+? store_vblank+0xe0/0xe0 [drm]
+hrtimer_cancel+0x15/0x30
+amdgpu_vkms_disable_vblank+0x15/0x30 [amdgpu]
+drm_vblank_disable_and_save+0x185/0x1f0 [drm]
+drm_crtc_vblank_off+0x159/0x4c0 [drm]
+? record_print_text.cold+0x11/0x11
+? wait_for_completion_timeout+0x232/0x280
+? drm_crtc_wait_one_vblank+0x40/0x40 [drm]
+? bit_wait_io_timeout+0xe0/0xe0
+? wait_for_completion_interruptible+0x1d7/0x320
+? mutex_unlock+0x81/0xd0
+amdgpu_vkms_crtc_atomic_disable
+
+It's caused by a stuck in lock dependency in such scenario on different
+CPUs.
+
+CPU1                                             CPU2
+drm_crtc_vblank_off                              hrtimer_interrupt
+    grab event_lock (irq disabled)                   __hrtimer_run_queues
+        grab vbl_lock/vblank_time_block                  amdgpu_vkms_vblank_simulate
+            amdgpu_vkms_disable_vblank                       drm_handle_vblank
+                hrtimer_cancel                                         grab dev->event_lock
+
+So CPU1 stucks in hrtimer_cancel as timer callback is running endless on
+current clock base, as that timer queue on CPU2 has no chance to finish it
+because of failing to hold the lock. So NMI watchdog will throw the errors
+after its threshold, and all later CPUs are impacted/blocked.
+
+So use hrtimer_try_to_cancel to fix this, as disable_vblank callback
+does not need to wait the handler to finish. And also it's not necessary
+to check the return value of hrtimer_try_to_cancel, because even if it's
+-1 which means current timer callback is running, it will be reprogrammed
+in hrtimer_start with calling enable_vblank to make it works.
+
+v2: only re-arm timer when vblank is enabled (Christian) and add a Fixes
+tag as well
+
+v3: drop warn printing (Christian)
+
+v4: drop superfluous check of blank->enabled in timer function, as it's
+guaranteed in drm_handle_vblank (Christian)
+
+Fixes: 84ec374bd580 ("drm/amdgpu: create amdgpu_vkms (v4)")
+Cc: stable@vger.kernel.org
+Suggested-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Guchun Chen <guchun.chen@amd.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
+@@ -55,8 +55,9 @@ static enum hrtimer_restart amdgpu_vkms_
+               DRM_WARN("%s: vblank timer overrun\n", __func__);
+       ret = drm_crtc_handle_vblank(crtc);
++      /* Don't queue timer again when vblank is disabled. */
+       if (!ret)
+-              DRM_ERROR("amdgpu_vkms failure on handling vblank");
++              return HRTIMER_NORESTART;
+       return HRTIMER_RESTART;
+ }
+@@ -81,7 +82,7 @@ static void amdgpu_vkms_disable_vblank(s
+ {
+       struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
+-      hrtimer_cancel(&amdgpu_crtc->vblank_timer);
++      hrtimer_try_to_cancel(&amdgpu_crtc->vblank_timer);
+ }
+ static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc *crtc,
diff --git a/queue-6.4/drm-client-fix-memory-leak-in-drm_client_modeset_probe.patch b/queue-6.4/drm-client-fix-memory-leak-in-drm_client_modeset_probe.patch
new file mode 100644 (file)
index 0000000..a9ac372
--- /dev/null
@@ -0,0 +1,46 @@
+From 2329cc7a101af1a844fbf706c0724c0baea38365 Mon Sep 17 00:00:00 2001
+From: Jocelyn Falempe <jfalempe@redhat.com>
+Date: Tue, 11 Jul 2023 11:20:44 +0200
+Subject: drm/client: Fix memory leak in drm_client_modeset_probe
+
+From: Jocelyn Falempe <jfalempe@redhat.com>
+
+commit 2329cc7a101af1a844fbf706c0724c0baea38365 upstream.
+
+When a new mode is set to modeset->mode, the previous mode should be freed.
+This fixes the following kmemleak report:
+
+drm_mode_duplicate+0x45/0x220 [drm]
+drm_client_modeset_probe+0x944/0xf50 [drm]
+__drm_fb_helper_initial_config_and_unlock+0xb4/0x2c0 [drm_kms_helper]
+drm_fbdev_client_hotplug+0x2bc/0x4d0 [drm_kms_helper]
+drm_client_register+0x169/0x240 [drm]
+ast_pci_probe+0x142/0x190 [ast]
+local_pci_probe+0xdc/0x180
+work_for_cpu_fn+0x4e/0xa0
+process_one_work+0x8b7/0x1540
+worker_thread+0x70a/0xed0
+kthread+0x29f/0x340
+ret_from_fork+0x1f/0x30
+
+cc: <stable@vger.kernel.org>
+Reported-by: Zhang Yi <yizhan@redhat.com>
+Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230711092203.68157-3-jfalempe@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/drm_client_modeset.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/gpu/drm/drm_client_modeset.c
++++ b/drivers/gpu/drm/drm_client_modeset.c
+@@ -867,6 +867,7 @@ int drm_client_modeset_probe(struct drm_
+                               break;
+                       }
++                      kfree(modeset->mode);
+                       modeset->mode = drm_mode_duplicate(dev, mode);
+                       drm_connector_get(connector);
+                       modeset->connectors[modeset->num_connectors++] = connector;
diff --git a/queue-6.4/drm-client-fix-memory-leak-in-drm_client_target_cloned.patch b/queue-6.4/drm-client-fix-memory-leak-in-drm_client_target_cloned.patch
new file mode 100644 (file)
index 0000000..05491d1
--- /dev/null
@@ -0,0 +1,68 @@
+From c2a88e8bdf5f6239948d75283d0ae7e0c7945b03 Mon Sep 17 00:00:00 2001
+From: Jocelyn Falempe <jfalempe@redhat.com>
+Date: Tue, 11 Jul 2023 11:20:43 +0200
+Subject: drm/client: Fix memory leak in drm_client_target_cloned
+
+From: Jocelyn Falempe <jfalempe@redhat.com>
+
+commit c2a88e8bdf5f6239948d75283d0ae7e0c7945b03 upstream.
+
+dmt_mode is allocated and never freed in this function.
+It was found with the ast driver, but most drivers using generic fbdev
+setup are probably affected.
+
+This fixes the following kmemleak report:
+  backtrace:
+    [<00000000b391296d>] drm_mode_duplicate+0x45/0x220 [drm]
+    [<00000000e45bb5b3>] drm_client_target_cloned.constprop.0+0x27b/0x480 [drm]
+    [<00000000ed2d3a37>] drm_client_modeset_probe+0x6bd/0xf50 [drm]
+    [<0000000010e5cc9d>] __drm_fb_helper_initial_config_and_unlock+0xb4/0x2c0 [drm_kms_helper]
+    [<00000000909f82ca>] drm_fbdev_client_hotplug+0x2bc/0x4d0 [drm_kms_helper]
+    [<00000000063a69aa>] drm_client_register+0x169/0x240 [drm]
+    [<00000000a8c61525>] ast_pci_probe+0x142/0x190 [ast]
+    [<00000000987f19bb>] local_pci_probe+0xdc/0x180
+    [<000000004fca231b>] work_for_cpu_fn+0x4e/0xa0
+    [<0000000000b85301>] process_one_work+0x8b7/0x1540
+    [<000000003375b17c>] worker_thread+0x70a/0xed0
+    [<00000000b0d43cd9>] kthread+0x29f/0x340
+    [<000000008d770833>] ret_from_fork+0x1f/0x30
+unreferenced object 0xff11000333089a00 (size 128):
+
+cc: <stable@vger.kernel.org>
+Fixes: 1d42bbc8f7f9 ("drm/fbdev: fix cloning on fbcon")
+Reported-by: Zhang Yi <yizhan@redhat.com>
+Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230711092203.68157-2-jfalempe@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/drm_client_modeset.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/gpu/drm/drm_client_modeset.c
++++ b/drivers/gpu/drm/drm_client_modeset.c
+@@ -311,6 +311,9 @@ static bool drm_client_target_cloned(str
+       can_clone = true;
+       dmt_mode = drm_mode_find_dmt(dev, 1024, 768, 60, false);
++      if (!dmt_mode)
++              goto fail;
++
+       for (i = 0; i < connector_count; i++) {
+               if (!enabled[i])
+                       continue;
+@@ -326,11 +329,13 @@ static bool drm_client_target_cloned(str
+               if (!modes[i])
+                       can_clone = false;
+       }
++      kfree(dmt_mode);
+       if (can_clone) {
+               DRM_DEBUG_KMS("can clone using 1024x768\n");
+               return true;
+       }
++fail:
+       DRM_INFO("kms: can't enable cloning when we probably wanted to.\n");
+       return false;
+ }
diff --git a/queue-6.4/drm-nouveau-disp-pior-dp-uses-gpio-for-hpd-not-pmgr-aux-interrupts.patch b/queue-6.4/drm-nouveau-disp-pior-dp-uses-gpio-for-hpd-not-pmgr-aux-interrupts.patch
new file mode 100644 (file)
index 0000000..16a88f3
--- /dev/null
@@ -0,0 +1,63 @@
+From 2b5d1c29f6c4cb19369ef92881465e5ede75f4ef Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Wed, 19 Jul 2023 14:40:50 +1000
+Subject: drm/nouveau/disp: PIOR DP uses GPIO for HPD, not PMGR AUX interrupts
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit 2b5d1c29f6c4cb19369ef92881465e5ede75f4ef upstream.
+
+Fixes crash on boards with ANX9805 TMDS/DP encoders.
+
+Cc: stable@vger.kernel.org # 6.4+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Reviewed-by: Karol Herbst <kherbst@redhat.com>
+Signed-off-by: Karol Herbst <kherbst@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230719044051.6975-2-skeggsb@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c |   29 +++++++++++++++--------
+ 1 file changed, 19 insertions(+), 10 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c
+@@ -81,20 +81,29 @@ nvkm_uconn_uevent(struct nvkm_object *ob
+               return -ENOSYS;
+       list_for_each_entry(outp, &conn->disp->outps, head) {
+-              if (outp->info.connector == conn->index && outp->dp.aux) {
+-                      if (args->v0.types & NVIF_CONN_EVENT_V0_PLUG  ) bits |= NVKM_I2C_PLUG;
+-                      if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |= NVKM_I2C_UNPLUG;
+-                      if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ   ) bits |= NVKM_I2C_IRQ;
+-
+-                      return nvkm_uevent_add(uevent, &device->i2c->event, outp->dp.aux->id, bits,
+-                                             nvkm_uconn_uevent_aux);
+-              }
++              if (outp->info.connector == conn->index)
++                      break;
++      }
++
++      if (&outp->head == &conn->disp->outps)
++              return -EINVAL;
++
++      if (outp->dp.aux && !outp->info.location) {
++              if (args->v0.types & NVIF_CONN_EVENT_V0_PLUG  ) bits |= NVKM_I2C_PLUG;
++              if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |= NVKM_I2C_UNPLUG;
++              if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ   ) bits |= NVKM_I2C_IRQ;
++
++              return nvkm_uevent_add(uevent, &device->i2c->event, outp->dp.aux->id, bits,
++                                     nvkm_uconn_uevent_aux);
+       }
+       if (args->v0.types & NVIF_CONN_EVENT_V0_PLUG  ) bits |= NVKM_GPIO_HI;
+       if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |= NVKM_GPIO_LO;
+-      if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ)
+-              return -EINVAL;
++      if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ) {
++              /* TODO: support DP IRQ on ANX9805 and remove this hack. */
++              if (!outp->info.location)
++                      return -EINVAL;
++      }
+       return nvkm_uevent_add(uevent, &device->gpio->event, conn->info.hpd, bits,
+                              nvkm_uconn_uevent_gpio);
diff --git a/queue-6.4/drm-nouveau-i2c-fix-number-of-aux-event-slots.patch b/queue-6.4/drm-nouveau-i2c-fix-number-of-aux-event-slots.patch
new file mode 100644 (file)
index 0000000..c9bf0d5
--- /dev/null
@@ -0,0 +1,83 @@
+From 752a281032b2d6f4564be827e082bde6f7d2fd4f Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Wed, 19 Jul 2023 14:40:49 +1000
+Subject: drm/nouveau/i2c: fix number of aux event slots
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit 752a281032b2d6f4564be827e082bde6f7d2fd4f upstream.
+
+This was completely bogus before, using maximum DCB device index rather
+than maximum AUX ID to size the buffer that stores event refcounts.
+
+*Pretty* unlikely to have been an actual problem on most configurations,
+that is, unless you've got one of the rare boards that have off-chip DP.
+
+There, it'll likely crash.
+
+Cc: stable@vger.kernel.org # 6.4+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Reviewed-by: Karol Herbst <kherbst@redhat.com>
+Signed-off-by: Karol Herbst <kherbst@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230719044051.6975-1-skeggsb@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h |  4 ++--
+ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c    | 11 +++++++++--
+ 2 files changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h
+index 40a1065ae626..ef441dfdea09 100644
+--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h
++++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h
+@@ -16,7 +16,7 @@ struct nvkm_i2c_bus {
+       const struct nvkm_i2c_bus_func *func;
+       struct nvkm_i2c_pad *pad;
+ #define NVKM_I2C_BUS_CCB(n) /* 'n' is ccb index */                           (n)
+-#define NVKM_I2C_BUS_EXT(n) /* 'n' is dcb external encoder type */ ((n) + 0x100)
++#define NVKM_I2C_BUS_EXT(n) /* 'n' is dcb external encoder type */  ((n) + 0x10)
+ #define NVKM_I2C_BUS_PRI /* ccb primary comm. port */                        -1
+ #define NVKM_I2C_BUS_SEC /* ccb secondary comm. port */                      -2
+       int id;
+@@ -38,7 +38,7 @@ struct nvkm_i2c_aux {
+       const struct nvkm_i2c_aux_func *func;
+       struct nvkm_i2c_pad *pad;
+ #define NVKM_I2C_AUX_CCB(n) /* 'n' is ccb index */                           (n)
+-#define NVKM_I2C_AUX_EXT(n) /* 'n' is dcb external encoder type */ ((n) + 0x100)
++#define NVKM_I2C_AUX_EXT(n) /* 'n' is dcb external encoder type */  ((n) + 0x10)
+       int id;
+       struct mutex mutex;
+diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c
+index 976539de4220..731b2f68d3db 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c
+@@ -260,10 +260,11 @@ nvkm_i2c_new_(const struct nvkm_i2c_func *func, struct nvkm_device *device,
+ {
+       struct nvkm_bios *bios = device->bios;
+       struct nvkm_i2c *i2c;
++      struct nvkm_i2c_aux *aux;
+       struct dcb_i2c_entry ccbE;
+       struct dcb_output dcbE;
+       u8 ver, hdr;
+-      int ret, i;
++      int ret, i, ids;
+       if (!(i2c = *pi2c = kzalloc(sizeof(*i2c), GFP_KERNEL)))
+               return -ENOMEM;
+@@ -406,5 +407,11 @@ nvkm_i2c_new_(const struct nvkm_i2c_func *func, struct nvkm_device *device,
+               }
+       }
+-      return nvkm_event_init(&nvkm_i2c_intr_func, &i2c->subdev, 4, i, &i2c->event);
++      ids = 0;
++      list_for_each_entry(aux, &i2c->aux, head)
++              ids = max(ids, aux->id + 1);
++      if (!ids)
++              return 0;
++
++      return nvkm_event_init(&nvkm_i2c_intr_func, &i2c->subdev, 4, ids, &i2c->event);
+ }
+-- 
+2.41.0
+
diff --git a/queue-6.4/drm-nouveau-kms-nv50-init-hpd_irq_lock-for-pior-dp.patch b/queue-6.4/drm-nouveau-kms-nv50-init-hpd_irq_lock-for-pior-dp.patch
new file mode 100644 (file)
index 0000000..0860926
--- /dev/null
@@ -0,0 +1,41 @@
+From ea293f823a8805735d9e00124df81a8f448ed1ae Mon Sep 17 00:00:00 2001
+From: Ben Skeggs <bskeggs@redhat.com>
+Date: Wed, 19 Jul 2023 14:40:51 +1000
+Subject: drm/nouveau/kms/nv50-: init hpd_irq_lock for PIOR DP
+
+From: Ben Skeggs <bskeggs@redhat.com>
+
+commit ea293f823a8805735d9e00124df81a8f448ed1ae upstream.
+
+Fixes OOPS on boards with ANX9805 DP encoders.
+
+Cc: stable@vger.kernel.org # 6.4+
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Reviewed-by: Karol Herbst <kherbst@redhat.com>
+Signed-off-by: Karol Herbst <kherbst@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230719044051.6975-3-skeggsb@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/nouveau/dispnv50/disp.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
++++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
+@@ -1873,6 +1873,8 @@ nv50_pior_destroy(struct drm_encoder *en
+       nvif_outp_dtor(&nv_encoder->outp);
+       drm_encoder_cleanup(encoder);
++
++      mutex_destroy(&nv_encoder->dp.hpd_irq_lock);
+       kfree(encoder);
+ }
+@@ -1917,6 +1919,8 @@ nv50_pior_create(struct drm_connector *c
+       nv_encoder->i2c = ddc;
+       nv_encoder->aux = aux;
++      mutex_init(&nv_encoder->dp.hpd_irq_lock);
++
+       encoder = to_drm_encoder(nv_encoder);
+       encoder->possible_crtcs = dcbe->heads;
+       encoder->possible_clones = 0;
diff --git a/queue-6.4/ia64-mmap-consider-pgoff-when-searching-for-free-mapping.patch b/queue-6.4/ia64-mmap-consider-pgoff-when-searching-for-free-mapping.patch
new file mode 100644 (file)
index 0000000..ed3cef9
--- /dev/null
@@ -0,0 +1,42 @@
+From 07e981137f17e5275b6fa5fd0c28b0ddb4519702 Mon Sep 17 00:00:00 2001
+From: Helge Deller <deller@gmx.de>
+Date: Fri, 21 Jul 2023 17:24:32 +0200
+Subject: ia64: mmap: Consider pgoff when searching for free mapping
+
+From: Helge Deller <deller@gmx.de>
+
+commit 07e981137f17e5275b6fa5fd0c28b0ddb4519702 upstream.
+
+IA64 is the only architecture which does not consider the pgoff value when
+searching for a possible free memory region with vm_unmapped_area().
+Adding this seems to have no negative side effect on IA64, so add it now
+to make IA64 consistent with all other architectures.
+
+Cc: stable@vger.kernel.org # 6.4
+Signed-off-by: Helge Deller <deller@gmx.de>
+Tested-by: matoro <matoro_mailinglist_kernel@matoro.tk>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: linux-ia64@vger.kernel.org
+Link: https://lore.kernel.org/r/20230721152432.196382-3-deller@gmx.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/ia64/kernel/sys_ia64.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
+index 6e948d015332..eb561cc93632 100644
+--- a/arch/ia64/kernel/sys_ia64.c
++++ b/arch/ia64/kernel/sys_ia64.c
+@@ -63,7 +63,7 @@ arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len
+       info.low_limit = addr;
+       info.high_limit = TASK_SIZE;
+       info.align_mask = align_mask;
+-      info.align_offset = 0;
++      info.align_offset = pgoff << PAGE_SHIFT;
+       return vm_unmapped_area(&info);
+ }
+-- 
+2.41.0
+
diff --git a/queue-6.4/of-preserve-of-display-device-name-for-compatibility.patch b/queue-6.4/of-preserve-of-display-device-name-for-compatibility.patch
new file mode 100644 (file)
index 0000000..2af0884
--- /dev/null
@@ -0,0 +1,51 @@
+From 0bb8f49cd2cc8cb32ac51189ff9fcbe7ec3d9d65 Mon Sep 17 00:00:00 2001
+From: Rob Herring <robh@kernel.org>
+Date: Mon, 10 Jul 2023 11:40:07 -0600
+Subject: of: Preserve "of-display" device name for compatibility
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rob Herring <robh@kernel.org>
+
+commit 0bb8f49cd2cc8cb32ac51189ff9fcbe7ec3d9d65 upstream.
+
+Since commit 241d2fb56a18 ("of: Make OF framebuffer device names unique"),
+as spotted by Frédéric Bonnard, the historical "of-display" device is
+gone: the updated logic creates "of-display.0" instead, then as many
+"of-display.N" as required.
+
+This means that offb no longer finds the expected device, which prevents
+the Debian Installer from setting up its interface, at least on ppc64el.
+
+Fix this by keeping "of-display" for the first device and "of-display.N"
+for subsequent devices.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=217328
+Link: https://bugs.debian.org/1033058
+Fixes: 241d2fb56a18 ("of: Make OF framebuffer device names unique")
+Cc: stable@vger.kernel.org
+Cc: Cyril Brulebois <cyril@debamax.com>
+Cc: Thomas Zimmermann <tzimmermann@suse.de>
+Cc: Helge Deller <deller@gmx.de>
+Acked-by: Helge Deller <deller@gmx.de>
+Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+Reviewed-by: Michal Suchánek <msuchanek@suse.de>
+Link: https://lore.kernel.org/r/20230710174007.2291013-1-robh@kernel.org
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/of/platform.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/of/platform.c
++++ b/drivers/of/platform.c
+@@ -553,7 +553,7 @@ static int __init of_platform_default_po
+                       if (!of_get_property(node, "linux,opened", NULL) ||
+                           !of_get_property(node, "linux,boot-display", NULL))
+                               continue;
+-                      dev = of_platform_device_create(node, "of-display.0", NULL);
++                      dev = of_platform_device_create(node, "of-display", NULL);
+                       of_node_put(node);
+                       if (WARN_ON(!dev))
+                               return -ENOMEM;
diff --git a/queue-6.4/regmap-account-for-register-length-in-smbus-i-o-limits.patch b/queue-6.4/regmap-account-for-register-length-in-smbus-i-o-limits.patch
new file mode 100644 (file)
index 0000000..b920fc5
--- /dev/null
@@ -0,0 +1,54 @@
+From 0c9d2eb5e94792fe64019008a04d4df5e57625af Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@kernel.org>
+Date: Wed, 12 Jul 2023 12:16:40 +0100
+Subject: regmap: Account for register length in SMBus I/O limits
+
+From: Mark Brown <broonie@kernel.org>
+
+commit 0c9d2eb5e94792fe64019008a04d4df5e57625af upstream.
+
+The SMBus I2C buses have limits on the size of transfers they can do but
+do not factor in the register length meaning we may try to do a transfer
+longer than our length limit, the core will not take care of this.
+Future changes will factor this out into the core but there are a number
+of users that assume current behaviour so let's just do something
+conservative here.
+
+This does not take account padding bits but practically speaking these
+are very rarely if ever used on I2C buses given that they generally run
+slowly enough to mean there's no issue.
+
+Cc: stable@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Reviewed-by: Xu Yilun <yilun.xu@intel.com>
+Link: https://lore.kernel.org/r/20230712-regmap-max-transfer-v1-2-80e2aed22e83@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/regmap/regmap-i2c.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/base/regmap/regmap-i2c.c
++++ b/drivers/base/regmap/regmap-i2c.c
+@@ -242,8 +242,8 @@ static int regmap_i2c_smbus_i2c_read(voi
+ static const struct regmap_bus regmap_i2c_smbus_i2c_block = {
+       .write = regmap_i2c_smbus_i2c_write,
+       .read = regmap_i2c_smbus_i2c_read,
+-      .max_raw_read = I2C_SMBUS_BLOCK_MAX,
+-      .max_raw_write = I2C_SMBUS_BLOCK_MAX,
++      .max_raw_read = I2C_SMBUS_BLOCK_MAX - 1,
++      .max_raw_write = I2C_SMBUS_BLOCK_MAX - 1,
+ };
+ static int regmap_i2c_smbus_i2c_write_reg16(void *context, const void *data,
+@@ -299,8 +299,8 @@ static int regmap_i2c_smbus_i2c_read_reg
+ static const struct regmap_bus regmap_i2c_smbus_i2c_block_reg16 = {
+       .write = regmap_i2c_smbus_i2c_write_reg16,
+       .read = regmap_i2c_smbus_i2c_read_reg16,
+-      .max_raw_read = I2C_SMBUS_BLOCK_MAX,
+-      .max_raw_write = I2C_SMBUS_BLOCK_MAX,
++      .max_raw_read = I2C_SMBUS_BLOCK_MAX - 2,
++      .max_raw_write = I2C_SMBUS_BLOCK_MAX - 2,
+ };
+ static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
diff --git a/queue-6.4/regmap-drop-initial-version-of-maximum-transfer-length-fixes.patch b/queue-6.4/regmap-drop-initial-version-of-maximum-transfer-length-fixes.patch
new file mode 100644 (file)
index 0000000..65305f8
--- /dev/null
@@ -0,0 +1,64 @@
+From bc64734825c59e18a27ac266b07e14944c111fd8 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@kernel.org>
+Date: Wed, 12 Jul 2023 12:16:39 +0100
+Subject: regmap: Drop initial version of maximum transfer length fixes
+
+From: Mark Brown <broonie@kernel.org>
+
+commit bc64734825c59e18a27ac266b07e14944c111fd8 upstream.
+
+When problems were noticed with the register address not being taken
+into account when limiting raw transfers with I2C devices we fixed this
+in the core.  Unfortunately it has subsequently been realised that a lot
+of buses were relying on the prior behaviour, partly due to unclear
+documentation not making it obvious what was intended in the core.  This
+is all more involved to fix than is sensible for a fix commit so let's
+just drop the original fixes, a separate commit will fix the originally
+observed problem in an I2C specific way
+
+Fixes: 3981514180c9 ("regmap: Account for register length when chunking")
+Fixes: c8e796895e23 ("regmap: spi-avmm: Fix regmap_bus max_raw_write")
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Reviewed-by: Xu Yilun <yilun.xu@intel.com>
+Cc: stable@kernel.org
+Link: https://lore.kernel.org/r/20230712-regmap-max-transfer-v1-1-80e2aed22e83@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/regmap/regmap-spi-avmm.c |    2 +-
+ drivers/base/regmap/regmap.c          |    6 ++----
+ 2 files changed, 3 insertions(+), 5 deletions(-)
+
+--- a/drivers/base/regmap/regmap-spi-avmm.c
++++ b/drivers/base/regmap/regmap-spi-avmm.c
+@@ -660,7 +660,7 @@ static const struct regmap_bus regmap_sp
+       .reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
+       .val_format_endian_default = REGMAP_ENDIAN_NATIVE,
+       .max_raw_read = SPI_AVMM_VAL_SIZE * MAX_READ_CNT,
+-      .max_raw_write = SPI_AVMM_REG_SIZE + SPI_AVMM_VAL_SIZE * MAX_WRITE_CNT,
++      .max_raw_write = SPI_AVMM_VAL_SIZE * MAX_WRITE_CNT,
+       .free_context = spi_avmm_bridge_ctx_free,
+ };
+--- a/drivers/base/regmap/regmap.c
++++ b/drivers/base/regmap/regmap.c
+@@ -2082,8 +2082,6 @@ int _regmap_raw_write(struct regmap *map
+       size_t val_count = val_len / val_bytes;
+       size_t chunk_count, chunk_bytes;
+       size_t chunk_regs = val_count;
+-      size_t max_data = map->max_raw_write - map->format.reg_bytes -
+-                      map->format.pad_bytes;
+       int ret, i;
+       if (!val_count)
+@@ -2091,8 +2089,8 @@ int _regmap_raw_write(struct regmap *map
+       if (map->use_single_write)
+               chunk_regs = 1;
+-      else if (map->max_raw_write && val_len > max_data)
+-              chunk_regs = max_data / val_bytes;
++      else if (map->max_raw_write && val_len > map->max_raw_write)
++              chunk_regs = map->max_raw_write / val_bytes;
+       chunk_count = val_count / chunk_regs;
+       chunk_bytes = chunk_regs * val_bytes;
diff --git a/queue-6.4/revert-r8169-disable-aspm-during-napi-poll.patch b/queue-6.4/revert-r8169-disable-aspm-during-napi-poll.patch
new file mode 100644 (file)
index 0000000..c73014b
--- /dev/null
@@ -0,0 +1,52 @@
+From e31a9fedc7d8d80722b19628e66fcb5a36981780 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Tue, 18 Jul 2023 13:12:32 +0200
+Subject: Revert "r8169: disable ASPM during NAPI poll"
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+commit e31a9fedc7d8d80722b19628e66fcb5a36981780 upstream.
+
+This reverts commit e1ed3e4d91112027b90c7ee61479141b3f948e6a.
+
+Turned out the change causes a performance regression.
+
+Link: https://lore.kernel.org/netdev/20230713124914.GA12924@green245/T/
+Cc: stable@vger.kernel.org
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/055c6bc2-74fa-8c67-9897-3f658abb5ae7@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c |   11 +----------
+ 1 file changed, 1 insertion(+), 10 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -4514,10 +4514,6 @@ static irqreturn_t rtl8169_interrupt(int
+       }
+       if (napi_schedule_prep(&tp->napi)) {
+-              rtl_unlock_config_regs(tp);
+-              rtl_hw_aspm_clkreq_enable(tp, false);
+-              rtl_lock_config_regs(tp);
+-
+               rtl_irq_disable(tp);
+               __napi_schedule(&tp->napi);
+       }
+@@ -4577,14 +4573,9 @@ static int rtl8169_poll(struct napi_stru
+       work_done = rtl_rx(dev, tp, budget);
+-      if (work_done < budget && napi_complete_done(napi, work_done)) {
++      if (work_done < budget && napi_complete_done(napi, work_done))
+               rtl_irq_enable(tp);
+-              rtl_unlock_config_regs(tp);
+-              rtl_hw_aspm_clkreq_enable(tp, true);
+-              rtl_lock_config_regs(tp);
+-      }
+-
+       return work_done;
+ }
diff --git a/queue-6.4/s390-zcrypt-fix-reply-buffer-calculations-for-cca-replies.patch b/queue-6.4/s390-zcrypt-fix-reply-buffer-calculations-for-cca-replies.patch
new file mode 100644 (file)
index 0000000..fd5360b
--- /dev/null
@@ -0,0 +1,93 @@
+From 4cfca532ddc3474b3fc42592d0e4237544344b1a Mon Sep 17 00:00:00 2001
+From: Harald Freudenberger <freude@linux.ibm.com>
+Date: Mon, 17 Jul 2023 16:55:29 +0200
+Subject: s390/zcrypt: fix reply buffer calculations for CCA replies
+
+From: Harald Freudenberger <freude@linux.ibm.com>
+
+commit 4cfca532ddc3474b3fc42592d0e4237544344b1a upstream.
+
+The length information for available buffer space for CCA
+replies is covered with two fields in the T6 header prepended
+on each CCA reply: fromcardlen1 and fromcardlen2. The sum of
+these both values must not exceed the AP bus limit for this
+card (24KB for CEX8, 12KB CEX7 and older) minus the always
+present headers.
+
+The current code adjusted the fromcardlen2 value in case
+of exceeding the AP bus limit when there was a non-zero
+value given from userspace. Some tests now showed that this
+was the wrong assumption. Instead the userspace value given for
+this field should always be trusted and if the sum of the
+two fields exceeds the AP bus limit for this card the first
+field fromcardlen1 should be adjusted instead.
+
+So now the calculation is done with this new insight in mind.
+Also some additional checks for overflow have been introduced
+and some comments to provide some documentation for future
+maintainers of this complicated calculation code.
+
+Furthermore the 128 bytes of fix overhead which is used
+in the current code is not correct. Investigations showed
+that for a reply always the same two header structs are
+prepended before a possible payload. So this is also fixed
+with this patch.
+
+Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
+Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/s390/crypto/zcrypt_msgtype6.c |   33 +++++++++++++++++++++++----------
+ 1 file changed, 23 insertions(+), 10 deletions(-)
+
+--- a/drivers/s390/crypto/zcrypt_msgtype6.c
++++ b/drivers/s390/crypto/zcrypt_msgtype6.c
+@@ -1111,23 +1111,36 @@ static long zcrypt_msgtype6_send_cprb(bo
+                                     struct ica_xcRB *xcrb,
+                                     struct ap_message *ap_msg)
+ {
+-      int rc;
+       struct response_type *rtype = ap_msg->private;
+       struct {
+               struct type6_hdr hdr;
+               struct CPRBX cprbx;
+               /* ... more data blocks ... */
+       } __packed * msg = ap_msg->msg;
++      unsigned int max_payload_size;
++      int rc, delta;
+-      /*
+-       * Set the queue's reply buffer length minus 128 byte padding
+-       * as reply limit for the card firmware.
+-       */
+-      msg->hdr.fromcardlen1 = min_t(unsigned int, msg->hdr.fromcardlen1,
+-                                    zq->reply.bufsize - 128);
+-      if (msg->hdr.fromcardlen2)
+-              msg->hdr.fromcardlen2 =
+-                      zq->reply.bufsize - msg->hdr.fromcardlen1 - 128;
++      /* calculate maximum payload for this card and msg type */
++      max_payload_size = zq->reply.bufsize - sizeof(struct type86_fmt2_msg);
++
++      /* limit each of the two from fields to the maximum payload size */
++      msg->hdr.fromcardlen1 = min(msg->hdr.fromcardlen1, max_payload_size);
++      msg->hdr.fromcardlen2 = min(msg->hdr.fromcardlen2, max_payload_size);
++
++      /* calculate delta if the sum of both exceeds max payload size */
++      delta = msg->hdr.fromcardlen1 + msg->hdr.fromcardlen2
++              - max_payload_size;
++      if (delta > 0) {
++              /*
++               * Sum exceeds maximum payload size, prune fromcardlen1
++               * (always trust fromcardlen2)
++               */
++              if (delta > msg->hdr.fromcardlen1) {
++                      rc = -EINVAL;
++                      goto out;
++              }
++              msg->hdr.fromcardlen1 -= delta;
++      }
+       init_completion(&rtype->work);
+       rc = ap_queue_message(zq->queue, ap_msg);
diff --git a/queue-6.4/selftests-tc-add-conntrack-procfs-kconfig.patch b/queue-6.4/selftests-tc-add-conntrack-procfs-kconfig.patch
new file mode 100644 (file)
index 0000000..cdab180
--- /dev/null
@@ -0,0 +1,42 @@
+From 031c99e71fedcce93b6785d38b7d287bf59e3952 Mon Sep 17 00:00:00 2001
+From: Matthieu Baerts <matthieu.baerts@tessares.net>
+Date: Thu, 13 Jul 2023 23:16:46 +0200
+Subject: selftests: tc: add ConnTrack procfs kconfig
+
+From: Matthieu Baerts <matthieu.baerts@tessares.net>
+
+commit 031c99e71fedcce93b6785d38b7d287bf59e3952 upstream.
+
+When looking at the TC selftest reports, I noticed one test was failing
+because /proc/net/nf_conntrack was not available.
+
+  not ok 373 3992 - Add ct action triggering DNAT tuple conflict
+       Could not match regex pattern. Verify command output:
+  cat: /proc/net/nf_conntrack: No such file or directory
+
+It is only available if NF_CONNTRACK_PROCFS kconfig is set. So the issue
+can be fixed simply by adding it to the list of required kconfig.
+
+Fixes: e46905641316 ("tc-testing: add test for ct DNAT tuple collision")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/netdev/0e061d4a-9a23-9f58-3b35-d8919de332d7@tessares.net/T/ [1]
+Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Tested-by: Zhengchao Shao <shaozhengchao@huawei.com>
+Link: https://lore.kernel.org/r/20230713-tc-selftests-lkft-v1-3-1eb4fd3a96e7@tessares.net
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/tc-testing/config |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/tools/testing/selftests/tc-testing/config
++++ b/tools/testing/selftests/tc-testing/config
+@@ -5,6 +5,7 @@ CONFIG_NF_CONNTRACK=m
+ CONFIG_NF_CONNTRACK_MARK=y
+ CONFIG_NF_CONNTRACK_ZONES=y
+ CONFIG_NF_CONNTRACK_LABELS=y
++CONFIG_NF_CONNTRACK_PROCFS=y
+ CONFIG_NF_FLOW_TABLE=m
+ CONFIG_NF_NAT=m
+ CONFIG_NETFILTER_XT_TARGET_LOG=m
index fac95b45371763f00c2c9d27a8dbc9e74c94b524..f480c0c67476244ec1dc46cd28705607687a40cf 100644 (file)
@@ -25,3 +25,47 @@ btrfs-fix-race-between-balance-and-cancel-pause.patch
 selftests-tc-set-timeout-to-15-minutes.patch
 accel-qaic-fix-a-leak-in-map_user_pages.patch
 selftests-tc-add-ct-action-kconfig-dep.patch
+regmap-drop-initial-version-of-maximum-transfer-length-fixes.patch
+s390-zcrypt-fix-reply-buffer-calculations-for-cca-replies.patch
+of-preserve-of-display-device-name-for-compatibility.patch
+regmap-account-for-register-length-in-smbus-i-o-limits.patch
+ia64-mmap-consider-pgoff-when-searching-for-free-mapping.patch
+arm64-fpsimd-ensure-sme-storage-is-allocated-after-sve-vl-changes.patch
+can-raw-fix-receiver-memory-leak.patch
+can-mcp251xfd-__mcp251xfd_chip_set_mode-increase-poll-timeout.patch
+can-bcm-fix-uaf-in-bcm_proc_show.patch
+can-gs_usb-gs_can_open-improve-error-handling.patch
+can-gs_usb-fix-time-stamp-counter-initialization.patch
+revert-r8169-disable-aspm-during-napi-poll.patch
+selftests-tc-add-conntrack-procfs-kconfig.patch
+accel-qaic-tighten-bounds-checking-in-encode_message.patch
+accel-qaic-tighten-bounds-checking-in-decode_message.patch
+accel-qaic-add-consistent-integer-overflow-checks.patch
+dma-buf-dma-resv-stop-leaking-on-krealloc-failure.patch
+drm-amdgpu-vkms-relax-timer-deactivation-by-hrtimer_try_to_cancel.patch
+drm-amdgpu-pm-make-gfxclock-consistent-for-sienna-cichlid.patch
+drm-amdgpu-pm-make-mclk-consistent-for-smu-13.0.7.patch
+drm-nouveau-disp-pior-dp-uses-gpio-for-hpd-not-pmgr-aux-interrupts.patch
+drm-nouveau-kms-nv50-init-hpd_irq_lock-for-pior-dp.patch
+drm-nouveau-i2c-fix-number-of-aux-event-slots.patch
+drm-client-fix-memory-leak-in-drm_client_target_cloned.patch
+drm-client-fix-memory-leak-in-drm_client_modeset_probe.patch
+drm-amd-display-only-accept-async-flips-for-fast-updates.patch
+drm-amd-display-disable-mpc-split-by-default-on-special-asic.patch
+drm-amd-display-check-tg-is-non-null-before-checking-if-enabled.patch
+drm-amd-display-keep-phy-active-for-dp-displays-on-dcn31.patch
+asoc-fsl_sai-disable-bit-clock-with-transmitter.patch
+asoc-fsl_sai-revert-asoc-fsl_sai-enable-mctl_mclk_en-bit-for-master-mode.patch
+asoc-tegra-fix-adx-byte-map.patch
+asoc-rt5640-fix-sleep-in-atomic-context.patch
+asoc-cs42l51-fix-driver-to-properly-autoload-with-automatic-module-loading.patch
+asoc-codecs-wcd938x-fix-missing-clsh-ctrl-error-handling.patch
+asoc-cs35l45-select-regmap_irq.patch
+asoc-codecs-wcd-mbhc-v2-fix-resource-leaks-on-component-remove.patch
+asoc-qdsp6-audioreach-fix-topology-probe-deferral.patch
+asoc-tegra-fix-amx-byte-map.patch
+asoc-codecs-wcd938x-fix-resource-leaks-on-component-remove.patch
+asoc-codecs-wcd938x-fix-missing-mbhc-init-error-handling.patch
+asoc-codecs-wcd934x-fix-resource-leaks-on-component-remove.patch
+asoc-codecs-wcd938x-fix-codec-initialisation-race.patch
+asoc-codecs-wcd938x-fix-soundwire-initialisation-race.patch