]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.16
authorSasha Levin <sashal@kernel.org>
Sat, 26 Feb 2022 02:59:30 +0000 (21:59 -0500)
committerSasha Levin <sashal@kernel.org>
Sat, 26 Feb 2022 02:59:30 +0000 (21:59 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
14 files changed:
queue-5.16/bnxt_en-increase-firmware-message-response-dma-wait-.patch [new file with mode: 0644]
queue-5.16/bpf-extend-kfunc-with-ptr_to_ctx-ptr_to_mem-argument.patch [new file with mode: 0644]
queue-5.16/bpf-fix-crash-due-to-out-of-bounds-access-into-reg2b.patch [new file with mode: 0644]
queue-5.16/configfs-fix-a-race-in-configfs_-un-register_subsyst.patch [new file with mode: 0644]
queue-5.16/gpio-rockchip-reset-int_bothedge-when-changing-trigg.patch [new file with mode: 0644]
queue-5.16/net-timestamp-convert-sk-sk_tskey-to-atomic_t.patch [new file with mode: 0644]
queue-5.16/net-use-sk_is_tcp-in-more-places.patch [new file with mode: 0644]
queue-5.16/pci-mvebu-fix-device-enumeration-regression.patch [new file with mode: 0644]
queue-5.16/rdma-ib_srp-fix-a-deadlock.patch [new file with mode: 0644]
queue-5.16/rdma-rtrs-clt-fix-possible-double-free-in-error-case.patch [new file with mode: 0644]
queue-5.16/rdma-rtrs-clt-move-free_permit-from-free_clt-to-rtrs.patch [new file with mode: 0644]
queue-5.16/regmap-irq-update-interrupt-clear-register-for-prope.patch [new file with mode: 0644]
queue-5.16/series
queue-5.16/spi-spi-zynq-qspi-fix-a-null-pointer-dereference-in-.patch [new file with mode: 0644]

diff --git a/queue-5.16/bnxt_en-increase-firmware-message-response-dma-wait-.patch b/queue-5.16/bnxt_en-increase-firmware-message-response-dma-wait-.patch
new file mode 100644 (file)
index 0000000..1bab57b
--- /dev/null
@@ -0,0 +1,80 @@
+From 32c4537f96859fd231766b84eb28c622a1ad39db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Feb 2022 04:05:52 -0500
+Subject: bnxt_en: Increase firmware message response DMA wait time
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+[ Upstream commit b891106da52b2c12dbaf73400f6d225b06a38d80 ]
+
+When polling for the firmware message response, we first poll for the
+response message header.  Once the valid length is detected in the
+header, we poll for the valid bit at the end of the message which
+signals DMA completion.  Normally, this poll time for DMA completion
+is extremely short (0 to a few usec).  But on some devices under some
+rare conditions, it can be up to about 20 msec.
+
+Increase this delay to 50 msec and use udelay() for the first 10 usec
+for the common case, and usleep_range() beyond that.
+
+Also, change the error message to include the above delay time when
+printing the timeout value.
+
+Fixes: 3c8c20db769c ("bnxt_en: move HWRM API implementation into separate file")
+Reviewed-by: Vladimir Olovyannikov <vladimir.olovyannikov@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c | 12 +++++++++---
+ drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.h |  2 +-
+ 2 files changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c
+index 8171f4912fa01..3a0eeb3737767 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c
+@@ -595,18 +595,24 @@ static int __hwrm_send(struct bnxt *bp, struct bnxt_hwrm_ctx *ctx)
+               /* Last byte of resp contains valid bit */
+               valid = ((u8 *)ctx->resp) + len - 1;
+-              for (j = 0; j < HWRM_VALID_BIT_DELAY_USEC; j++) {
++              for (j = 0; j < HWRM_VALID_BIT_DELAY_USEC; ) {
+                       /* make sure we read from updated DMA memory */
+                       dma_rmb();
+                       if (*valid)
+                               break;
+-                      usleep_range(1, 5);
++                      if (j < 10) {
++                              udelay(1);
++                              j++;
++                      } else {
++                              usleep_range(20, 30);
++                              j += 20;
++                      }
+               }
+               if (j >= HWRM_VALID_BIT_DELAY_USEC) {
+                       if (!(ctx->flags & BNXT_HWRM_CTX_SILENT))
+                               netdev_err(bp->dev, "Error (timeout: %u) msg {0x%x 0x%x} len:%d v:%d\n",
+-                                         hwrm_total_timeout(i),
++                                         hwrm_total_timeout(i) + j,
+                                          le16_to_cpu(ctx->req->req_type),
+                                          le16_to_cpu(ctx->req->seq_id), len,
+                                          *valid);
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.h
+index 9a9fc4e8041b6..380ef69afb51b 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.h
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.h
+@@ -94,7 +94,7 @@ static inline unsigned int hwrm_total_timeout(unsigned int n)
+ }
+-#define HWRM_VALID_BIT_DELAY_USEC     150
++#define HWRM_VALID_BIT_DELAY_USEC     50000
+ static inline bool bnxt_cfa_hwrm_message(u16 req_type)
+ {
+-- 
+2.34.1
+
diff --git a/queue-5.16/bpf-extend-kfunc-with-ptr_to_ctx-ptr_to_mem-argument.patch b/queue-5.16/bpf-extend-kfunc-with-ptr_to_ctx-ptr_to_mem-argument.patch
new file mode 100644 (file)
index 0000000..bba1b7c
--- /dev/null
@@ -0,0 +1,194 @@
+From 1ae5145bc09526f2f6f800927240eb64de8c37d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Dec 2021 07:20:24 +0530
+Subject: bpf: Extend kfunc with PTR_TO_CTX, PTR_TO_MEM argument support
+
+From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+
+[ Upstream commit 3363bd0cfbb80dfcd25003cd3815b0ad8b68d0ff ]
+
+Allow passing PTR_TO_CTX, if the kfunc expects a matching struct type,
+and punt to PTR_TO_MEM block if reg->type does not fall in one of
+PTR_TO_BTF_ID or PTR_TO_SOCK* types. This will be used by future commits
+to get access to XDP and TC PTR_TO_CTX, and pass various data (flags,
+l4proto, netns_id, etc.) encoded in opts struct passed as pointer to
+kfunc.
+
+For PTR_TO_MEM support, arguments are currently limited to pointer to
+scalar, or pointer to struct composed of scalars. This is done so that
+unsafe scenarios (like passing PTR_TO_MEM where PTR_TO_BTF_ID of
+in-kernel valid structure is expected, which may have pointers) are
+avoided. Since the argument checking happens basd on argument register
+type, it is not easy to ascertain what the expected type is. In the
+future, support for PTR_TO_MEM for kfunc can be extended to serve other
+usecases. The struct type whose pointer is passed in may have maximum
+nesting depth of 4, all recursively composed of scalars or struct with
+scalars.
+
+Future commits will add negative tests that check whether these
+restrictions imposed for kfunc arguments are duly rejected by BPF
+verifier or not.
+
+Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20211217015031.1278167-4-memxor@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/btf.c | 94 +++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 73 insertions(+), 21 deletions(-)
+
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index d2ff8ba7ae58f..1621f9d45fbda 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -5564,12 +5564,53 @@ static u32 *reg2btf_ids[__BPF_REG_TYPE_MAX] = {
+ #endif
+ };
++/* Returns true if struct is composed of scalars, 4 levels of nesting allowed */
++static bool __btf_type_is_scalar_struct(struct bpf_verifier_log *log,
++                                      const struct btf *btf,
++                                      const struct btf_type *t, int rec)
++{
++      const struct btf_type *member_type;
++      const struct btf_member *member;
++      u32 i;
++
++      if (!btf_type_is_struct(t))
++              return false;
++
++      for_each_member(i, t, member) {
++              const struct btf_array *array;
++
++              member_type = btf_type_skip_modifiers(btf, member->type, NULL);
++              if (btf_type_is_struct(member_type)) {
++                      if (rec >= 3) {
++                              bpf_log(log, "max struct nesting depth exceeded\n");
++                              return false;
++                      }
++                      if (!__btf_type_is_scalar_struct(log, btf, member_type, rec + 1))
++                              return false;
++                      continue;
++              }
++              if (btf_type_is_array(member_type)) {
++                      array = btf_type_array(member_type);
++                      if (!array->nelems)
++                              return false;
++                      member_type = btf_type_skip_modifiers(btf, array->type, NULL);
++                      if (!btf_type_is_scalar(member_type))
++                              return false;
++                      continue;
++              }
++              if (!btf_type_is_scalar(member_type))
++                      return false;
++      }
++      return true;
++}
++
+ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
+                                   const struct btf *btf, u32 func_id,
+                                   struct bpf_reg_state *regs,
+                                   bool ptr_to_mem_ok)
+ {
+       struct bpf_verifier_log *log = &env->log;
++      bool is_kfunc = btf_is_kernel(btf);
+       const char *func_name, *ref_tname;
+       const struct btf_type *t, *ref_t;
+       const struct btf_param *args;
+@@ -5622,7 +5663,20 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
+               ref_t = btf_type_skip_modifiers(btf, t->type, &ref_id);
+               ref_tname = btf_name_by_offset(btf, ref_t->name_off);
+-              if (btf_is_kernel(btf)) {
++              if (btf_get_prog_ctx_type(log, btf, t,
++                                        env->prog->type, i)) {
++                      /* If function expects ctx type in BTF check that caller
++                       * is passing PTR_TO_CTX.
++                       */
++                      if (reg->type != PTR_TO_CTX) {
++                              bpf_log(log,
++                                      "arg#%d expected pointer to ctx, but got %s\n",
++                                      i, btf_type_str(t));
++                              return -EINVAL;
++                      }
++                      if (check_ctx_reg(env, reg, regno))
++                              return -EINVAL;
++              } else if (is_kfunc && (reg->type == PTR_TO_BTF_ID || reg2btf_ids[reg->type])) {
+                       const struct btf_type *reg_ref_t;
+                       const struct btf *reg_btf;
+                       const char *reg_ref_tname;
+@@ -5638,14 +5692,9 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
+                       if (reg->type == PTR_TO_BTF_ID) {
+                               reg_btf = reg->btf;
+                               reg_ref_id = reg->btf_id;
+-                      } else if (reg2btf_ids[reg->type]) {
++                      } else {
+                               reg_btf = btf_vmlinux;
+                               reg_ref_id = *reg2btf_ids[reg->type];
+-                      } else {
+-                              bpf_log(log, "kernel function %s args#%d expected pointer to %s %s but R%d is not a pointer to btf_id\n",
+-                                      func_name, i,
+-                                      btf_type_str(ref_t), ref_tname, regno);
+-                              return -EINVAL;
+                       }
+                       reg_ref_t = btf_type_skip_modifiers(reg_btf, reg_ref_id,
+@@ -5661,23 +5710,24 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
+                                       reg_ref_tname);
+                               return -EINVAL;
+                       }
+-              } else if (btf_get_prog_ctx_type(log, btf, t,
+-                                               env->prog->type, i)) {
+-                      /* If function expects ctx type in BTF check that caller
+-                       * is passing PTR_TO_CTX.
+-                       */
+-                      if (reg->type != PTR_TO_CTX) {
+-                              bpf_log(log,
+-                                      "arg#%d expected pointer to ctx, but got %s\n",
+-                                      i, btf_type_str(t));
+-                              return -EINVAL;
+-                      }
+-                      if (check_ctx_reg(env, reg, regno))
+-                              return -EINVAL;
+               } else if (ptr_to_mem_ok) {
+                       const struct btf_type *resolve_ret;
+                       u32 type_size;
++                      if (is_kfunc) {
++                              /* Permit pointer to mem, but only when argument
++                               * type is pointer to scalar, or struct composed
++                               * (recursively) of scalars.
++                               */
++                              if (!btf_type_is_scalar(ref_t) &&
++                                  !__btf_type_is_scalar_struct(log, btf, ref_t, 0)) {
++                                      bpf_log(log,
++                                              "arg#%d pointer type %s %s must point to scalar or struct with scalar\n",
++                                              i, btf_type_str(ref_t), ref_tname);
++                                      return -EINVAL;
++                              }
++                      }
++
+                       resolve_ret = btf_resolve_size(btf, ref_t, &type_size);
+                       if (IS_ERR(resolve_ret)) {
+                               bpf_log(log,
+@@ -5690,6 +5740,8 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
+                       if (check_mem_reg(env, reg, regno, type_size))
+                               return -EINVAL;
+               } else {
++                      bpf_log(log, "reg type unsupported for arg#%d %sfunction %s#%d\n", i,
++                              is_kfunc ? "kernel " : "", func_name, func_id);
+                       return -EINVAL;
+               }
+       }
+@@ -5739,7 +5791,7 @@ int btf_check_kfunc_arg_match(struct bpf_verifier_env *env,
+                             const struct btf *btf, u32 func_id,
+                             struct bpf_reg_state *regs)
+ {
+-      return btf_check_func_arg_match(env, btf, func_id, regs, false);
++      return btf_check_func_arg_match(env, btf, func_id, regs, true);
+ }
+ /* Convert BTF of a function into bpf_reg_state if possible
+-- 
+2.34.1
+
diff --git a/queue-5.16/bpf-fix-crash-due-to-out-of-bounds-access-into-reg2b.patch b/queue-5.16/bpf-fix-crash-due-to-out-of-bounds-access-into-reg2b.patch
new file mode 100644 (file)
index 0000000..4858a2a
--- /dev/null
@@ -0,0 +1,54 @@
+From ebb84ee5390911770b34d58e634ada2884436c92 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Feb 2022 01:49:43 +0530
+Subject: bpf: Fix crash due to out of bounds access into reg2btf_ids.
+
+From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+
+[ Upstream commit 45ce4b4f9009102cd9f581196d480a59208690c1 ]
+
+When commit e6ac2450d6de ("bpf: Support bpf program calling kernel function") added
+kfunc support, it defined reg2btf_ids as a cheap way to translate the verifier
+reg type to the appropriate btf_vmlinux BTF ID, however
+commit c25b2ae13603 ("bpf: Replace PTR_TO_XXX_OR_NULL with PTR_TO_XXX | PTR_MAYBE_NULL")
+moved the __BPF_REG_TYPE_MAX from the last member of bpf_reg_type enum to after
+the base register types, and defined other variants using type flag
+composition. However, now, the direct usage of reg->type to index into
+reg2btf_ids may no longer fall into __BPF_REG_TYPE_MAX range, and hence lead to
+out of bounds access and kernel crash on dereference of bad pointer.
+
+Fixes: c25b2ae13603 ("bpf: Replace PTR_TO_XXX_OR_NULL with PTR_TO_XXX | PTR_MAYBE_NULL")
+Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20220216201943.624869-1-memxor@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/btf.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index 1621f9d45fbda..c9da250fee38c 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -5676,7 +5676,8 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
+                       }
+                       if (check_ctx_reg(env, reg, regno))
+                               return -EINVAL;
+-              } else if (is_kfunc && (reg->type == PTR_TO_BTF_ID || reg2btf_ids[reg->type])) {
++              } else if (is_kfunc && (reg->type == PTR_TO_BTF_ID ||
++                         (reg2btf_ids[base_type(reg->type)] && !type_flag(reg->type)))) {
+                       const struct btf_type *reg_ref_t;
+                       const struct btf *reg_btf;
+                       const char *reg_ref_tname;
+@@ -5694,7 +5695,7 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
+                               reg_ref_id = reg->btf_id;
+                       } else {
+                               reg_btf = btf_vmlinux;
+-                              reg_ref_id = *reg2btf_ids[reg->type];
++                              reg_ref_id = *reg2btf_ids[base_type(reg->type)];
+                       }
+                       reg_ref_t = btf_type_skip_modifiers(reg_btf, reg_ref_id,
+-- 
+2.34.1
+
diff --git a/queue-5.16/configfs-fix-a-race-in-configfs_-un-register_subsyst.patch b/queue-5.16/configfs-fix-a-race-in-configfs_-un-register_subsyst.patch
new file mode 100644 (file)
index 0000000..310aa05
--- /dev/null
@@ -0,0 +1,98 @@
+From 9de226fef96ea43dd70b2551e3ba7adfeaa4b752 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Feb 2022 15:10:30 +0800
+Subject: configfs: fix a race in configfs_{,un}register_subsystem()
+
+From: ChenXiaoSong <chenxiaosong2@huawei.com>
+
+[ Upstream commit 84ec758fb2daa236026506868c8796b0500c047d ]
+
+When configfs_register_subsystem() or configfs_unregister_subsystem()
+is executing link_group() or unlink_group(),
+it is possible that two processes add or delete list concurrently.
+Some unfortunate interleavings of them can cause kernel panic.
+
+One of cases is:
+A --> B --> C --> D
+A <-- B <-- C <-- D
+
+     delete list_head *B        |      delete list_head *C
+--------------------------------|-----------------------------------
+configfs_unregister_subsystem   |   configfs_unregister_subsystem
+  unlink_group                  |     unlink_group
+    unlink_obj                  |       unlink_obj
+      list_del_init             |         list_del_init
+        __list_del_entry        |           __list_del_entry
+          __list_del            |             __list_del
+            // next == C        |
+            next->prev = prev   |
+                                |               next->prev = prev
+            prev->next = next   |
+                                |                 // prev == B
+                                |                 prev->next = next
+
+Fix this by adding mutex when calling link_group() or unlink_group(),
+but parent configfs_subsystem is NULL when config_item is root.
+So I create a mutex configfs_subsystem_mutex.
+
+Fixes: 7063fbf22611 ("[PATCH] configfs: User-driven configuration filesystem")
+Signed-off-by: ChenXiaoSong <chenxiaosong2@huawei.com>
+Signed-off-by: Laibin Qiu <qiulaibin@huawei.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/configfs/dir.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
+index d3cd2a94d1e8c..d1f9d26322027 100644
+--- a/fs/configfs/dir.c
++++ b/fs/configfs/dir.c
+@@ -34,6 +34,14 @@
+  */
+ DEFINE_SPINLOCK(configfs_dirent_lock);
++/*
++ * All of link_obj/unlink_obj/link_group/unlink_group require that
++ * subsys->su_mutex is held.
++ * But parent configfs_subsystem is NULL when config_item is root.
++ * Use this mutex when config_item is root.
++ */
++static DEFINE_MUTEX(configfs_subsystem_mutex);
++
+ static void configfs_d_iput(struct dentry * dentry,
+                           struct inode * inode)
+ {
+@@ -1859,7 +1867,9 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
+               group->cg_item.ci_name = group->cg_item.ci_namebuf;
+       sd = root->d_fsdata;
++      mutex_lock(&configfs_subsystem_mutex);
+       link_group(to_config_group(sd->s_element), group);
++      mutex_unlock(&configfs_subsystem_mutex);
+       inode_lock_nested(d_inode(root), I_MUTEX_PARENT);
+@@ -1884,7 +1894,9 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
+       inode_unlock(d_inode(root));
+       if (err) {
++              mutex_lock(&configfs_subsystem_mutex);
+               unlink_group(group);
++              mutex_unlock(&configfs_subsystem_mutex);
+               configfs_release_fs();
+       }
+       put_fragment(frag);
+@@ -1931,7 +1943,9 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys)
+       dput(dentry);
++      mutex_lock(&configfs_subsystem_mutex);
+       unlink_group(group);
++      mutex_unlock(&configfs_subsystem_mutex);
+       configfs_release_fs();
+ }
+-- 
+2.34.1
+
diff --git a/queue-5.16/gpio-rockchip-reset-int_bothedge-when-changing-trigg.patch b/queue-5.16/gpio-rockchip-reset-int_bothedge-when-changing-trigg.patch
new file mode 100644 (file)
index 0000000..fb864ce
--- /dev/null
@@ -0,0 +1,104 @@
+From 6c7c50972edafd78de91dac2638306572bcc707e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Feb 2022 14:50:48 -0600
+Subject: gpio: rockchip: Reset int_bothedge when changing trigger
+
+From: Samuel Holland <samuel@sholland.org>
+
+[ Upstream commit 7920af5c826cb4a7ada1ae26fdd317642805adc2 ]
+
+With v2 hardware, an IRQ can be configured to trigger on both edges via
+a bit in the int_bothedge register. Currently, the driver sets this bit
+when changing the trigger type to IRQ_TYPE_EDGE_BOTH, but fails to reset
+this bit if the trigger type is later changed to something else. This
+causes spurious IRQs, and when using gpio-keys with wakeup-event-action
+set to EV_ACT_(DE)ASSERTED, those IRQs translate into spurious wakeups.
+
+Fixes: 3bcbd1a85b68 ("gpio/rockchip: support next version gpio controller")
+Reported-by: Guillaume Savaton <guillaume@baierouge.fr>
+Tested-by: Guillaume Savaton <guillaume@baierouge.fr>
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-rockchip.c | 56 +++++++++++++++++++-----------------
+ 1 file changed, 29 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
+index ce63cbd14d69a..24155c038f6d0 100644
+--- a/drivers/gpio/gpio-rockchip.c
++++ b/drivers/gpio/gpio-rockchip.c
+@@ -410,10 +410,8 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
+       level = rockchip_gpio_readl(bank, bank->gpio_regs->int_type);
+       polarity = rockchip_gpio_readl(bank, bank->gpio_regs->int_polarity);
+-      switch (type) {
+-      case IRQ_TYPE_EDGE_BOTH:
++      if (type == IRQ_TYPE_EDGE_BOTH) {
+               if (bank->gpio_type == GPIO_TYPE_V2) {
+-                      bank->toggle_edge_mode &= ~mask;
+                       rockchip_gpio_writel_bit(bank, d->hwirq, 1,
+                                                bank->gpio_regs->int_bothedge);
+                       goto out;
+@@ -431,30 +429,34 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
+                       else
+                               polarity |= mask;
+               }
+-              break;
+-      case IRQ_TYPE_EDGE_RISING:
+-              bank->toggle_edge_mode &= ~mask;
+-              level |= mask;
+-              polarity |= mask;
+-              break;
+-      case IRQ_TYPE_EDGE_FALLING:
+-              bank->toggle_edge_mode &= ~mask;
+-              level |= mask;
+-              polarity &= ~mask;
+-              break;
+-      case IRQ_TYPE_LEVEL_HIGH:
+-              bank->toggle_edge_mode &= ~mask;
+-              level &= ~mask;
+-              polarity |= mask;
+-              break;
+-      case IRQ_TYPE_LEVEL_LOW:
+-              bank->toggle_edge_mode &= ~mask;
+-              level &= ~mask;
+-              polarity &= ~mask;
+-              break;
+-      default:
+-              ret = -EINVAL;
+-              goto out;
++      } else {
++              if (bank->gpio_type == GPIO_TYPE_V2) {
++                      rockchip_gpio_writel_bit(bank, d->hwirq, 0,
++                                               bank->gpio_regs->int_bothedge);
++              } else {
++                      bank->toggle_edge_mode &= ~mask;
++              }
++              switch (type) {
++              case IRQ_TYPE_EDGE_RISING:
++                      level |= mask;
++                      polarity |= mask;
++                      break;
++              case IRQ_TYPE_EDGE_FALLING:
++                      level |= mask;
++                      polarity &= ~mask;
++                      break;
++              case IRQ_TYPE_LEVEL_HIGH:
++                      level &= ~mask;
++                      polarity |= mask;
++                      break;
++              case IRQ_TYPE_LEVEL_LOW:
++                      level &= ~mask;
++                      polarity &= ~mask;
++                      break;
++              default:
++                      ret = -EINVAL;
++                      goto out;
++              }
+       }
+       rockchip_gpio_writel(bank, level, bank->gpio_regs->int_type);
+-- 
+2.34.1
+
diff --git a/queue-5.16/net-timestamp-convert-sk-sk_tskey-to-atomic_t.patch b/queue-5.16/net-timestamp-convert-sk-sk_tskey-to-atomic_t.patch
new file mode 100644 (file)
index 0000000..c0af732
--- /dev/null
@@ -0,0 +1,164 @@
+From 4b4a4e8b5a8ae46ab86fe0511cf218123b7b42a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Feb 2022 09:05:02 -0800
+Subject: net-timestamp: convert sk->sk_tskey to atomic_t
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit a1cdec57e03a1352e92fbbe7974039dda4efcec0 ]
+
+UDP sendmsg() can be lockless, this is causing all kinds
+of data races.
+
+This patch converts sk->sk_tskey to remove one of these races.
+
+BUG: KCSAN: data-race in __ip_append_data / __ip_append_data
+
+read to 0xffff8881035d4b6c of 4 bytes by task 8877 on cpu 1:
+ __ip_append_data+0x1c1/0x1de0 net/ipv4/ip_output.c:994
+ ip_make_skb+0x13f/0x2d0 net/ipv4/ip_output.c:1636
+ udp_sendmsg+0x12bd/0x14c0 net/ipv4/udp.c:1249
+ inet_sendmsg+0x5f/0x80 net/ipv4/af_inet.c:819
+ sock_sendmsg_nosec net/socket.c:705 [inline]
+ sock_sendmsg net/socket.c:725 [inline]
+ ____sys_sendmsg+0x39a/0x510 net/socket.c:2413
+ ___sys_sendmsg net/socket.c:2467 [inline]
+ __sys_sendmmsg+0x267/0x4c0 net/socket.c:2553
+ __do_sys_sendmmsg net/socket.c:2582 [inline]
+ __se_sys_sendmmsg net/socket.c:2579 [inline]
+ __x64_sys_sendmmsg+0x53/0x60 net/socket.c:2579
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x44/0xd0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+write to 0xffff8881035d4b6c of 4 bytes by task 8880 on cpu 0:
+ __ip_append_data+0x1d8/0x1de0 net/ipv4/ip_output.c:994
+ ip_make_skb+0x13f/0x2d0 net/ipv4/ip_output.c:1636
+ udp_sendmsg+0x12bd/0x14c0 net/ipv4/udp.c:1249
+ inet_sendmsg+0x5f/0x80 net/ipv4/af_inet.c:819
+ sock_sendmsg_nosec net/socket.c:705 [inline]
+ sock_sendmsg net/socket.c:725 [inline]
+ ____sys_sendmsg+0x39a/0x510 net/socket.c:2413
+ ___sys_sendmsg net/socket.c:2467 [inline]
+ __sys_sendmmsg+0x267/0x4c0 net/socket.c:2553
+ __do_sys_sendmmsg net/socket.c:2582 [inline]
+ __se_sys_sendmmsg net/socket.c:2579 [inline]
+ __x64_sys_sendmmsg+0x53/0x60 net/socket.c:2579
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x44/0xd0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+value changed: 0x0000054d -> 0x0000054e
+
+Reported by Kernel Concurrency Sanitizer on:
+CPU: 0 PID: 8880 Comm: syz-executor.5 Not tainted 5.17.0-rc2-syzkaller-00167-gdcb85f85fa6f-dirty #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+
+Fixes: 09c2d251b707 ("net-timestamp: add key to disambiguate concurrent datagrams")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Willem de Bruijn <willemb@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sock.h        | 4 ++--
+ net/can/j1939/transport.c | 2 +-
+ net/core/skbuff.c         | 2 +-
+ net/core/sock.c           | 4 ++--
+ net/ipv4/ip_output.c      | 2 +-
+ net/ipv6/ip6_output.c     | 2 +-
+ 6 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 4e575735563a7..cd69595949614 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -504,7 +504,7 @@ struct sock {
+       u16                     sk_tsflags;
+       int                     sk_bind_phc;
+       u8                      sk_shutdown;
+-      u32                     sk_tskey;
++      atomic_t                sk_tskey;
+       atomic_t                sk_zckey;
+       u8                      sk_clockid;
+@@ -2636,7 +2636,7 @@ static inline void _sock_tx_timestamp(struct sock *sk, __u16 tsflags,
+               __sock_tx_timestamp(tsflags, tx_flags);
+               if (tsflags & SOF_TIMESTAMPING_OPT_ID && tskey &&
+                   tsflags & SOF_TIMESTAMPING_TX_RECORD_MASK)
+-                      *tskey = sk->sk_tskey++;
++                      *tskey = atomic_inc_return(&sk->sk_tskey) - 1;
+       }
+       if (unlikely(sock_flag(sk, SOCK_WIFI_STATUS)))
+               *tx_flags |= SKBTX_WIFI_STATUS;
+diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
+index a271688780a2c..307ee1174a6e2 100644
+--- a/net/can/j1939/transport.c
++++ b/net/can/j1939/transport.c
+@@ -2006,7 +2006,7 @@ struct j1939_session *j1939_tp_send(struct j1939_priv *priv,
+               /* set the end-packet for broadcast */
+               session->pkt.last = session->pkt.total;
+-      skcb->tskey = session->sk->sk_tskey++;
++      skcb->tskey = atomic_inc_return(&session->sk->sk_tskey) - 1;
+       session->tskey = skcb->tskey;
+       return session;
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 2b2e19afef158..f78969d8d8160 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -4850,7 +4850,7 @@ static void __skb_complete_tx_timestamp(struct sk_buff *skb,
+       if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) {
+               serr->ee.ee_data = skb_shinfo(skb)->tskey;
+               if (sk_is_tcp(sk))
+-                      serr->ee.ee_data -= sk->sk_tskey;
++                      serr->ee.ee_data -= atomic_read(&sk->sk_tskey);
+       }
+       err = sock_queue_err_skb(sk, skb);
+diff --git a/net/core/sock.c b/net/core/sock.c
+index d18e4ffd84820..6613a864f7f5a 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -878,9 +878,9 @@ int sock_set_timestamping(struct sock *sk, int optname,
+                       if ((1 << sk->sk_state) &
+                           (TCPF_CLOSE | TCPF_LISTEN))
+                               return -EINVAL;
+-                      sk->sk_tskey = tcp_sk(sk)->snd_una;
++                      atomic_set(&sk->sk_tskey, tcp_sk(sk)->snd_una);
+               } else {
+-                      sk->sk_tskey = 0;
++                      atomic_set(&sk->sk_tskey, 0);
+               }
+       }
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+index a4d2eb691cbc1..131066d0319a2 100644
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -992,7 +992,7 @@ static int __ip_append_data(struct sock *sk,
+       if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP &&
+           sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)
+-              tskey = sk->sk_tskey++;
++              tskey = atomic_inc_return(&sk->sk_tskey) - 1;
+       hh_len = LL_RESERVED_SPACE(rt->dst.dev);
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index ff4e83e2a5068..22bf8fb617165 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -1465,7 +1465,7 @@ static int __ip6_append_data(struct sock *sk,
+       if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP &&
+           sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)
+-              tskey = sk->sk_tskey++;
++              tskey = atomic_inc_return(&sk->sk_tskey) - 1;
+       hh_len = LL_RESERVED_SPACE(rt->dst.dev);
+-- 
+2.34.1
+
diff --git a/queue-5.16/net-use-sk_is_tcp-in-more-places.patch b/queue-5.16/net-use-sk_is_tcp-in-more-places.patch
new file mode 100644 (file)
index 0000000..d21bf41
--- /dev/null
@@ -0,0 +1,105 @@
+From eadbca7a7c6a036babedd57f3792c164dbfb0148 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Nov 2021 11:02:33 -0800
+Subject: net: use sk_is_tcp() in more places
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 42f67eea3ba36cef2dce2e853de6ddcb2e89eb39 ]
+
+Move sk_is_tcp() to include/net/sock.h and use it where we can.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/skmsg.h | 6 ------
+ include/net/sock.h    | 5 +++++
+ net/core/skbuff.c     | 6 ++----
+ net/core/sock.c       | 6 ++----
+ 4 files changed, 9 insertions(+), 14 deletions(-)
+
+diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h
+index 584d94be9c8b0..18a717fe62eb0 100644
+--- a/include/linux/skmsg.h
++++ b/include/linux/skmsg.h
+@@ -507,12 +507,6 @@ static inline bool sk_psock_strp_enabled(struct sk_psock *psock)
+       return !!psock->saved_data_ready;
+ }
+-static inline bool sk_is_tcp(const struct sock *sk)
+-{
+-      return sk->sk_type == SOCK_STREAM &&
+-             sk->sk_protocol == IPPROTO_TCP;
+-}
+-
+ static inline bool sk_is_udp(const struct sock *sk)
+ {
+       return sk->sk_type == SOCK_DGRAM &&
+diff --git a/include/net/sock.h b/include/net/sock.h
+index d47e9658da285..4e575735563a7 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -2654,6 +2654,11 @@ static inline void skb_setup_tx_timestamp(struct sk_buff *skb, __u16 tsflags)
+                          &skb_shinfo(skb)->tskey);
+ }
++static inline bool sk_is_tcp(const struct sock *sk)
++{
++      return sk->sk_type == SOCK_STREAM && sk->sk_protocol == IPPROTO_TCP;
++}
++
+ /**
+  * sk_eat_skb - Release a skb if it is no longer needed
+  * @sk: socket to eat this skb from
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 92edd03c2cd1c..2b2e19afef158 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -4849,8 +4849,7 @@ static void __skb_complete_tx_timestamp(struct sk_buff *skb,
+       serr->header.h4.iif = skb->dev ? skb->dev->ifindex : 0;
+       if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) {
+               serr->ee.ee_data = skb_shinfo(skb)->tskey;
+-              if (sk->sk_protocol == IPPROTO_TCP &&
+-                  sk->sk_type == SOCK_STREAM)
++              if (sk_is_tcp(sk))
+                       serr->ee.ee_data -= sk->sk_tskey;
+       }
+@@ -4919,8 +4918,7 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
+       if (tsonly) {
+ #ifdef CONFIG_INET
+               if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_STATS) &&
+-                  sk->sk_protocol == IPPROTO_TCP &&
+-                  sk->sk_type == SOCK_STREAM) {
++                  sk_is_tcp(sk)) {
+                       skb = tcp_get_timestamping_opt_stats(sk, orig_skb,
+                                                            ack_skb);
+                       opt_stats = true;
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 7de234693a3bf..d18e4ffd84820 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -874,8 +874,7 @@ int sock_set_timestamping(struct sock *sk, int optname,
+       if (val & SOF_TIMESTAMPING_OPT_ID &&
+           !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)) {
+-              if (sk->sk_protocol == IPPROTO_TCP &&
+-                  sk->sk_type == SOCK_STREAM) {
++              if (sk_is_tcp(sk)) {
+                       if ((1 << sk->sk_state) &
+                           (TCPF_CLOSE | TCPF_LISTEN))
+                               return -EINVAL;
+@@ -1372,8 +1371,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
+       case SO_ZEROCOPY:
+               if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6) {
+-                      if (!((sk->sk_type == SOCK_STREAM &&
+-                             sk->sk_protocol == IPPROTO_TCP) ||
++                      if (!(sk_is_tcp(sk) ||
+                             (sk->sk_type == SOCK_DGRAM &&
+                              sk->sk_protocol == IPPROTO_UDP)))
+                               ret = -ENOTSUPP;
+-- 
+2.34.1
+
diff --git a/queue-5.16/pci-mvebu-fix-device-enumeration-regression.patch b/queue-5.16/pci-mvebu-fix-device-enumeration-regression.patch
new file mode 100644 (file)
index 0000000..478a8ca
--- /dev/null
@@ -0,0 +1,54 @@
+From 989f6b43c9d52a98348a47b9ca65ec1880323fa2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Feb 2022 12:02:28 +0100
+Subject: PCI: mvebu: Fix device enumeration regression
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit c49ae619905eebd3f54598a84e4cd2bd58ba8fe9 ]
+
+Jan reported that on Turris Omnia (Armada 385), no PCIe devices were
+detected after upgrading from v5.16.1 to v5.16.3 and identified the cause
+as the backport of 91a8d79fc797 ("PCI: mvebu: Fix configuring secondary bus
+of PCIe Root Port via emulated bridge"), which appeared in v5.17-rc1.
+
+91a8d79fc797 was incorrectly applied from mailing list patch [1] to the
+linux git repository [2] probably due to resolving merge conflicts
+incorrectly. Fix it now.
+
+[1] https://lore.kernel.org/r/20211125124605.25915-12-pali@kernel.org
+[2] https://git.kernel.org/linus/91a8d79fc797
+
+[bhelgaas: commit log]
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=215540
+Fixes: 91a8d79fc797 ("PCI: mvebu: Fix configuring secondary bus of PCIe Root Port via emulated bridge")
+Link: https://lore.kernel.org/r/20220214110228.25825-1-pali@kernel.org
+Link: https://lore.kernel.org/r/20220127234917.GA150851@bhelgaas
+Reported-by: Jan Palus <jpalus@fastmail.com>
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pci-mvebu.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
+index 357e9a293edf7..2a3bf82aa4e26 100644
+--- a/drivers/pci/controller/pci-mvebu.c
++++ b/drivers/pci/controller/pci-mvebu.c
+@@ -1288,7 +1288,8 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
+                * indirectly via kernel emulated PCI bridge driver.
+                */
+               mvebu_pcie_setup_hw(port);
+-              mvebu_pcie_set_local_dev_nr(port, 0);
++              mvebu_pcie_set_local_dev_nr(port, 1);
++              mvebu_pcie_set_local_bus_nr(port, 0);
+       }
+       pcie->nports = i;
+-- 
+2.34.1
+
diff --git a/queue-5.16/rdma-ib_srp-fix-a-deadlock.patch b/queue-5.16/rdma-ib_srp-fix-a-deadlock.patch
new file mode 100644 (file)
index 0000000..570195a
--- /dev/null
@@ -0,0 +1,45 @@
+From 916228faaa106eb54a4c783f265299f904ffc427 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Feb 2022 13:05:11 -0800
+Subject: RDMA/ib_srp: Fix a deadlock
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 081bdc9fe05bb23248f5effb6f811da3da4b8252 ]
+
+Remove the flush_workqueue(system_long_wq) call since flushing
+system_long_wq is deadlock-prone and since that call is redundant with a
+preceding cancel_work_sync()
+
+Link: https://lore.kernel.org/r/20220215210511.28303-3-bvanassche@acm.org
+Fixes: ef6c49d87c34 ("IB/srp: Eliminate state SRP_TARGET_DEAD")
+Reported-by: syzbot+831661966588c802aae9@syzkaller.appspotmail.com
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/srp/ib_srp.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
+index e174e853f8a40..285b766e4e704 100644
+--- a/drivers/infiniband/ulp/srp/ib_srp.c
++++ b/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -4047,9 +4047,11 @@ static void srp_remove_one(struct ib_device *device, void *client_data)
+               spin_unlock(&host->target_lock);
+               /*
+-               * Wait for tl_err and target port removal tasks.
++               * srp_queue_remove_work() queues a call to
++               * srp_remove_target(). The latter function cancels
++               * target->tl_err_work so waiting for the remove works to
++               * finish is sufficient.
+                */
+-              flush_workqueue(system_long_wq);
+               flush_workqueue(srp_remove_wq);
+               kfree(host);
+-- 
+2.34.1
+
diff --git a/queue-5.16/rdma-rtrs-clt-fix-possible-double-free-in-error-case.patch b/queue-5.16/rdma-rtrs-clt-fix-possible-double-free-in-error-case.patch
new file mode 100644 (file)
index 0000000..bedde6c
--- /dev/null
@@ -0,0 +1,125 @@
+From 56bee86e6cdde0de5695443219f847506c8303c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Feb 2022 04:09:28 +0100
+Subject: RDMA/rtrs-clt: Fix possible double free in error case
+
+From: Md Haris Iqbal <haris.iqbal@ionos.com>
+
+[ Upstream commit 8700af2cc18c919b2a83e74e0479038fd113c15d ]
+
+Callback function rtrs_clt_dev_release() for put_device() calls kfree(clt)
+to free memory. We shouldn't call kfree(clt) again, and we can't use the
+clt after kfree too.
+
+Replace device_register() with device_initialize() and device_add() so that
+dev_set_name can() be used appropriately.
+
+Move mutex_destroy() to the release function so it can be called in
+the alloc_clt err path.
+
+Fixes: eab098246625 ("RDMA/rtrs-clt: Refactor the failure cases in alloc_clt")
+Link: https://lore.kernel.org/r/20220217030929.323849-1-haris.iqbal@ionos.com
+Reported-by: Miaoqian Lin <linmq006@gmail.com>
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-clt.c | 37 ++++++++++++++------------
+ 1 file changed, 20 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+index e39709dee179d..7760cbc098add 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+@@ -2664,6 +2664,8 @@ static void rtrs_clt_dev_release(struct device *dev)
+ {
+       struct rtrs_clt *clt = container_of(dev, struct rtrs_clt, dev);
++      mutex_destroy(&clt->paths_ev_mutex);
++      mutex_destroy(&clt->paths_mutex);
+       kfree(clt);
+ }
+@@ -2693,6 +2695,8 @@ static struct rtrs_clt *alloc_clt(const char *sessname, size_t paths_num,
+               return ERR_PTR(-ENOMEM);
+       }
++      clt->dev.class = rtrs_clt_dev_class;
++      clt->dev.release = rtrs_clt_dev_release;
+       uuid_gen(&clt->paths_uuid);
+       INIT_LIST_HEAD_RCU(&clt->paths_list);
+       clt->paths_num = paths_num;
+@@ -2709,43 +2713,41 @@ static struct rtrs_clt *alloc_clt(const char *sessname, size_t paths_num,
+       init_waitqueue_head(&clt->permits_wait);
+       mutex_init(&clt->paths_ev_mutex);
+       mutex_init(&clt->paths_mutex);
++      device_initialize(&clt->dev);
+-      clt->dev.class = rtrs_clt_dev_class;
+-      clt->dev.release = rtrs_clt_dev_release;
+       err = dev_set_name(&clt->dev, "%s", sessname);
+       if (err)
+-              goto err;
++              goto err_put;
++
+       /*
+        * Suppress user space notification until
+        * sysfs files are created
+        */
+       dev_set_uevent_suppress(&clt->dev, true);
+-      err = device_register(&clt->dev);
+-      if (err) {
+-              put_device(&clt->dev);
+-              goto err;
+-      }
++      err = device_add(&clt->dev);
++      if (err)
++              goto err_put;
+       clt->kobj_paths = kobject_create_and_add("paths", &clt->dev.kobj);
+       if (!clt->kobj_paths) {
+               err = -ENOMEM;
+-              goto err_dev;
++              goto err_del;
+       }
+       err = rtrs_clt_create_sysfs_root_files(clt);
+       if (err) {
+               kobject_del(clt->kobj_paths);
+               kobject_put(clt->kobj_paths);
+-              goto err_dev;
++              goto err_del;
+       }
+       dev_set_uevent_suppress(&clt->dev, false);
+       kobject_uevent(&clt->dev.kobj, KOBJ_ADD);
+       return clt;
+-err_dev:
+-      device_unregister(&clt->dev);
+-err:
++err_del:
++      device_del(&clt->dev);
++err_put:
+       free_percpu(clt->pcpu_path);
+-      kfree(clt);
++      put_device(&clt->dev);
+       return ERR_PTR(err);
+ }
+@@ -2753,9 +2755,10 @@ static void free_clt(struct rtrs_clt *clt)
+ {
+       free_permits(clt);
+       free_percpu(clt->pcpu_path);
+-      mutex_destroy(&clt->paths_ev_mutex);
+-      mutex_destroy(&clt->paths_mutex);
+-      /* release callback will free clt in last put */
++
++      /*
++       * release callback will free clt and destroy mutexes in last put
++       */
+       device_unregister(&clt->dev);
+ }
+-- 
+2.34.1
+
diff --git a/queue-5.16/rdma-rtrs-clt-move-free_permit-from-free_clt-to-rtrs.patch b/queue-5.16/rdma-rtrs-clt-move-free_permit-from-free_clt-to-rtrs.patch
new file mode 100644 (file)
index 0000000..5917dd2
--- /dev/null
@@ -0,0 +1,49 @@
+From c85acdee66e0a6f556cca0ddbae7f453aba1f4aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Feb 2022 04:09:29 +0100
+Subject: RDMA/rtrs-clt: Move free_permit from free_clt to rtrs_clt_close
+
+From: Md Haris Iqbal <haris.iqbal@ionos.com>
+
+[ Upstream commit c46fa8911b17e3f808679061a8af8bee219f4602 ]
+
+Error path of rtrs_clt_open() calls free_clt(), where free_permit is
+called.  This is wrong since error path of rtrs_clt_open() does not need
+to call free_permit().
+
+Also, moving free_permits() call to rtrs_clt_close(), makes it more
+aligned with the call to alloc_permit() in rtrs_clt_open().
+
+Fixes: 6a98d71daea1 ("RDMA/rtrs: client: main functionality")
+Link: https://lore.kernel.org/r/20220217030929.323849-2-haris.iqbal@ionos.com
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-clt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+index 7760cbc098add..be96701cf281e 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+@@ -2753,7 +2753,6 @@ static struct rtrs_clt *alloc_clt(const char *sessname, size_t paths_num,
+ static void free_clt(struct rtrs_clt *clt)
+ {
+-      free_permits(clt);
+       free_percpu(clt->pcpu_path);
+       /*
+@@ -2875,6 +2874,7 @@ void rtrs_clt_close(struct rtrs_clt *clt)
+               rtrs_clt_destroy_sess_files(sess, NULL);
+               kobject_put(&sess->kobj);
+       }
++      free_permits(clt);
+       free_clt(clt);
+ }
+ EXPORT_SYMBOL(rtrs_clt_close);
+-- 
+2.34.1
+
diff --git a/queue-5.16/regmap-irq-update-interrupt-clear-register-for-prope.patch b/queue-5.16/regmap-irq-update-interrupt-clear-register-for-prope.patch
new file mode 100644 (file)
index 0000000..649d5e6
--- /dev/null
@@ -0,0 +1,105 @@
+From 2a1a03d568272c9c66f24ee637b8539c9ddf00c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Feb 2022 14:20:07 +0530
+Subject: regmap-irq: Update interrupt clear register for proper reset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Prasad Kumpatla <quic_pkumpatl@quicinc.com>
+
+[ Upstream commit d04ad245d67a3991dfea5e108e4c452c2ab39bac ]
+
+With the existing logic where clear_ack is true (HW doesn’t support
+auto clear for ICR), interrupt clear register reset is not handled
+properly. Due to this only the first interrupts get processed properly
+and further interrupts are blocked due to not resetting interrupt
+clear register.
+
+Example for issue case where Invert_ack is false and clear_ack is true:
+
+    Say Default ISR=0x00 & ICR=0x00 and ISR is triggered with 2
+    interrupts making ISR = 0x11.
+
+    Step 1: Say ISR is set 0x11 (store status_buff = ISR). ISR needs to
+            be cleared with the help of ICR once the Interrupt is processed.
+
+    Step 2: Write ICR = 0x11 (status_buff), this will clear the ISR to 0x00.
+
+    Step 3: Issue - In the existing code, ICR is written with ICR =
+            ~(status_buff) i.e ICR = 0xEE -> This will block all the interrupts
+            from raising except for interrupts 0 and 4. So expectation here is to
+            reset ICR, which will unblock all the interrupts.
+
+            if (chip->clear_ack) {
+                 if (chip->ack_invert && !ret)
+                  ........
+                 else if (!ret)
+                     ret = regmap_write(map, reg,
+                            ~data->status_buf[i]);
+
+So writing 0 and 0xff (when ack_invert is true) should have no effect, other
+than clearing the ACKs just set.
+
+Fixes: 3a6f0fb7b8eb ("regmap: irq: Add support to clear ack registers")
+Signed-off-by: Prasad Kumpatla <quic_pkumpatl@quicinc.com>
+Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Link: https://lore.kernel.org/r/20220217085007.30218-1-quic_pkumpatl@quicinc.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/regmap/regmap-irq.c | 20 ++++++--------------
+ 1 file changed, 6 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
+index d2656581a6085..4a446259a184e 100644
+--- a/drivers/base/regmap/regmap-irq.c
++++ b/drivers/base/regmap/regmap-irq.c
+@@ -189,11 +189,9 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
+                               ret = regmap_write(map, reg, d->mask_buf[i]);
+                       if (d->chip->clear_ack) {
+                               if (d->chip->ack_invert && !ret)
+-                                      ret = regmap_write(map, reg,
+-                                                         d->mask_buf[i]);
++                                      ret = regmap_write(map, reg, UINT_MAX);
+                               else if (!ret)
+-                                      ret = regmap_write(map, reg,
+-                                                         ~d->mask_buf[i]);
++                                      ret = regmap_write(map, reg, 0);
+                       }
+                       if (ret != 0)
+                               dev_err(d->map->dev, "Failed to ack 0x%x: %d\n",
+@@ -556,11 +554,9 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
+                                               data->status_buf[i]);
+                       if (chip->clear_ack) {
+                               if (chip->ack_invert && !ret)
+-                                      ret = regmap_write(map, reg,
+-                                                      data->status_buf[i]);
++                                      ret = regmap_write(map, reg, UINT_MAX);
+                               else if (!ret)
+-                                      ret = regmap_write(map, reg,
+-                                                      ~data->status_buf[i]);
++                                      ret = regmap_write(map, reg, 0);
+                       }
+                       if (ret != 0)
+                               dev_err(map->dev, "Failed to ack 0x%x: %d\n",
+@@ -817,13 +813,9 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
+                                       d->status_buf[i] & d->mask_buf[i]);
+                       if (chip->clear_ack) {
+                               if (chip->ack_invert && !ret)
+-                                      ret = regmap_write(map, reg,
+-                                              (d->status_buf[i] &
+-                                               d->mask_buf[i]));
++                                      ret = regmap_write(map, reg, UINT_MAX);
+                               else if (!ret)
+-                                      ret = regmap_write(map, reg,
+-                                              ~(d->status_buf[i] &
+-                                                d->mask_buf[i]));
++                                      ret = regmap_write(map, reg, 0);
+                       }
+                       if (ret != 0) {
+                               dev_err(map->dev, "Failed to ack 0x%x: %d\n",
+-- 
+2.34.1
+
index 42f8667cc479119c9db2e54ab44ccea2ce6a07ae..810baaac80ea21feea9395b845c46a6f312ea373 100644 (file)
@@ -96,3 +96,16 @@ net-mlx5e-ktls-use-checksum_unnecessary-for-device-offloaded-packets.patch
 net-mlx5-dr-fix-slab-out-of-bounds-in-mlx5_cmd_dr_create_fte.patch
 net-mlx5-update-log_max_qp-value-to-be-17-at-most.patch
 net-mlx5e-add-missing-increment-of-count.patch
+spi-spi-zynq-qspi-fix-a-null-pointer-dereference-in-.patch
+pci-mvebu-fix-device-enumeration-regression.patch
+gpio-rockchip-reset-int_bothedge-when-changing-trigg.patch
+regmap-irq-update-interrupt-clear-register-for-prope.patch
+net-use-sk_is_tcp-in-more-places.patch
+net-timestamp-convert-sk-sk_tskey-to-atomic_t.patch
+rdma-rtrs-clt-fix-possible-double-free-in-error-case.patch
+rdma-rtrs-clt-move-free_permit-from-free_clt-to-rtrs.patch
+bnxt_en-increase-firmware-message-response-dma-wait-.patch
+configfs-fix-a-race-in-configfs_-un-register_subsyst.patch
+rdma-ib_srp-fix-a-deadlock.patch
+bpf-extend-kfunc-with-ptr_to_ctx-ptr_to_mem-argument.patch
+bpf-fix-crash-due-to-out-of-bounds-access-into-reg2b.patch
diff --git a/queue-5.16/spi-spi-zynq-qspi-fix-a-null-pointer-dereference-in-.patch b/queue-5.16/spi-spi-zynq-qspi-fix-a-null-pointer-dereference-in-.patch
new file mode 100644 (file)
index 0000000..d1aebad
--- /dev/null
@@ -0,0 +1,55 @@
+From 69e6c2b781a4df8f22e91097ad7cac3045a3773d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Dec 2021 01:22:53 +0800
+Subject: spi: spi-zynq-qspi: Fix a NULL pointer dereference in
+ zynq_qspi_exec_mem_op()
+
+From: Zhou Qingyang <zhou1615@umn.edu>
+
+[ Upstream commit ab3824427b848da10e9fe2727f035bbeecae6ff4 ]
+
+In zynq_qspi_exec_mem_op(), kzalloc() is directly used in memset(),
+which could lead to a NULL pointer dereference on failure of
+kzalloc().
+
+Fix this bug by adding a check of tmpbuf.
+
+This bug was found by a static analyzer. The analysis employs
+differential checking to identify inconsistent security operations
+(e.g., checks or kfrees) between two code paths and confirms that the
+inconsistent operations are not recovered in the current function or
+the callers, so they constitute bugs.
+
+Note that, as a bug found by static analysis, it can be a false
+positive or hard to trigger. Multiple researchers have cross-reviewed
+the bug.
+
+Builds with CONFIG_SPI_ZYNQ_QSPI=m show no new warnings,
+and our static analyzer no longer warns about this code.
+
+Fixes: 67dca5e580f1 ("spi: spi-mem: Add support for Zynq QSPI controller")
+Signed-off-by: Zhou Qingyang <zhou1615@umn.edu>
+Link: https://lore.kernel.org/r/20211130172253.203700-1-zhou1615@umn.edu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-zynq-qspi.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c
+index cfa222c9bd5e7..78f31b61a2aac 100644
+--- a/drivers/spi/spi-zynq-qspi.c
++++ b/drivers/spi/spi-zynq-qspi.c
+@@ -570,6 +570,9 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem,
+       if (op->dummy.nbytes) {
+               tmpbuf = kzalloc(op->dummy.nbytes, GFP_KERNEL);
++              if (!tmpbuf)
++                      return -ENOMEM;
++
+               memset(tmpbuf, 0xff, op->dummy.nbytes);
+               reinit_completion(&xqspi->data_completion);
+               xqspi->txbuf = tmpbuf;
+-- 
+2.34.1
+