--- /dev/null
+From 59257015ac8813d2430988aa01c2f4609a60e8e7 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Thu, 30 Mar 2023 09:13:33 +0200
+Subject: ASoC: dt-bindings: qcom,lpass-rx-macro: correct minItems for clocks
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+commit 59257015ac8813d2430988aa01c2f4609a60e8e7 upstream.
+
+The RX macro codec comes on some platforms in two variants - ADSP
+and ADSP bypassed - thus the clock-names varies from 3 to 5. The clocks
+must vary as well:
+
+ sc7280-idp.dtb: codec@3200000: clocks: [[202, 8], [202, 7], [203]] is too short
+
+Fixes: 852fda58d99a ("ASoC: qcom: dt-bindings: Update bindings for clocks in lpass digital codes")
+Cc: <stable@vger.kernel.org>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20230330071333.24308-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
++++ b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
+@@ -30,6 +30,7 @@ properties:
+ const: 0
+
+ clocks:
++ minItems: 3
+ maxItems: 5
+
+ clock-names:
--- /dev/null
+From 6a0c637bfee69a74c104468544d9f2a6579626d0 Mon Sep 17 00:00:00 2001
+From: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Date: Fri, 24 Mar 2023 10:13:04 -0600
+Subject: bus: mhi: host: Range check CHDBOFF and ERDBOFF
+
+From: Jeffrey Hugo <quic_jhugo@quicinc.com>
+
+commit 6a0c637bfee69a74c104468544d9f2a6579626d0 upstream.
+
+If the value read from the CHDBOFF and ERDBOFF registers is outside the
+range of the MHI register space then an invalid address might be computed
+which later causes a kernel panic. Range check the read value to prevent
+a crash due to bad data from the device.
+
+Fixes: 6cd330ae76ff ("bus: mhi: core: Add support for ringing channel/event ring doorbells")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Reviewed-by: Pranjal Ramajor Asha Kanojiya <quic_pkanojiy@quicinc.com>
+Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
+Link: https://lore.kernel.org/r/1679674384-27209-1-git-send-email-quic_jhugo@quicinc.com
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bus/mhi/host/init.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/bus/mhi/host/init.c
++++ b/drivers/bus/mhi/host/init.c
+@@ -516,6 +516,12 @@ int mhi_init_mmio(struct mhi_controller
+ return -EIO;
+ }
+
++ if (val >= mhi_cntrl->reg_len - (8 * MHI_DEV_WAKE_DB)) {
++ dev_err(dev, "CHDB offset: 0x%x is out of range: 0x%zx\n",
++ val, mhi_cntrl->reg_len - (8 * MHI_DEV_WAKE_DB));
++ return -ERANGE;
++ }
++
+ /* Setup wake db */
+ mhi_cntrl->wake_db = base + val + (8 * MHI_DEV_WAKE_DB);
+ mhi_cntrl->wake_set = false;
+@@ -532,6 +538,12 @@ int mhi_init_mmio(struct mhi_controller
+ return -EIO;
+ }
+
++ if (val >= mhi_cntrl->reg_len - (8 * mhi_cntrl->total_ev_rings)) {
++ dev_err(dev, "ERDB offset: 0x%x is out of range: 0x%zx\n",
++ val, mhi_cntrl->reg_len - (8 * mhi_cntrl->total_ev_rings));
++ return -ERANGE;
++ }
++
+ /* Setup event db address for each ev_ring */
+ mhi_event = mhi_cntrl->mhi_event;
+ for (i = 0; i < mhi_cntrl->total_ev_rings; i++, val += 8, mhi_event++) {
--- /dev/null
+From d469d9448a0f1a33c175d3280b1542fa0158ad7a Mon Sep 17 00:00:00 2001
+From: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Date: Mon, 10 Apr 2023 09:58:11 -0600
+Subject: bus: mhi: host: Remove duplicate ee check for syserr
+
+From: Jeffrey Hugo <quic_jhugo@quicinc.com>
+
+commit d469d9448a0f1a33c175d3280b1542fa0158ad7a upstream.
+
+If we detect a system error via intvec, we only process the syserr if the
+current ee is different than the last observed ee. The reason for this
+check is to prevent bhie from running multiple times, but with the single
+queue handling syserr, that is not possible.
+
+The check can cause an issue with device recovery. If PBL loads a bad SBL
+via BHI, but that SBL hangs before notifying the host of an ee change,
+then issuing soc_reset to crash the device and retry (after supplying a
+fixed SBL) will not recover the device as the host will observe a PBL->PBL
+transition and not process the syserr. The device will be stuck until
+either the driver is reloaded, or the host is rebooted. Instead, remove
+the check so that we can attempt to recover the device.
+
+Fixes: ef2126c4e2ea ("bus: mhi: core: Process execution environment changes serially")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Reviewed-by: Carl Vanderlip <quic_carlv@quicinc.com>
+Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
+Link: https://lore.kernel.org/r/1681142292-27571-2-git-send-email-quic_jhugo@quicinc.com
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bus/mhi/host/main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/bus/mhi/host/main.c
++++ b/drivers/bus/mhi/host/main.c
+@@ -503,7 +503,7 @@ irqreturn_t mhi_intvec_threaded_handler(
+ }
+ write_unlock_irq(&mhi_cntrl->pm_lock);
+
+- if (pm_state != MHI_PM_SYS_ERR_DETECT || ee == mhi_cntrl->ee)
++ if (pm_state != MHI_PM_SYS_ERR_DETECT)
+ goto exit_intvec;
+
+ switch (ee) {
--- /dev/null
+From 1d1493bdc25f498468a606a4ece947d155cfa3a9 Mon Sep 17 00:00:00 2001
+From: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Date: Mon, 10 Apr 2023 09:58:12 -0600
+Subject: bus: mhi: host: Use mhi_tryset_pm_state() for setting fw error state
+
+From: Jeffrey Hugo <quic_jhugo@quicinc.com>
+
+commit 1d1493bdc25f498468a606a4ece947d155cfa3a9 upstream.
+
+If firmware loading fails, the controller's pm_state is updated to
+MHI_PM_FW_DL_ERR unconditionally. This can corrupt the pm_state as the
+update is not done under the proper lock, and also does not validate
+the state transition. The firmware loading can fail due to a detected
+syserr, but if MHI_PM_FW_DL_ERR is unconditionally set as the pm_state,
+the handling of the syserr can break when it attempts to transition from
+syserr detect, to syserr process.
+
+By grabbing the lock, we ensure we don't race with some other pm_state
+update. By using mhi_try_set_pm_state(), we check that the transition
+to MHI_PM_FW_DL_ERR is valid via the state machine logic. If it is not
+valid, then some other transition is occurring like syserr processing, and
+we assume that will resolve the firmware loading error.
+
+Fixes: 12e050c77be0 ("bus: mhi: core: Move to an error state on any firmware load failure")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Reviewed-by: Carl Vanderlip <quic_carlv@quicinc.com>
+Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
+Link: https://lore.kernel.org/r/1681142292-27571-3-git-send-email-quic_jhugo@quicinc.com
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bus/mhi/host/boot.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+--- a/drivers/bus/mhi/host/boot.c
++++ b/drivers/bus/mhi/host/boot.c
+@@ -391,6 +391,7 @@ void mhi_fw_load_handler(struct mhi_cont
+ {
+ const struct firmware *firmware = NULL;
+ struct device *dev = &mhi_cntrl->mhi_dev->dev;
++ enum mhi_pm_state new_state;
+ const char *fw_name;
+ void *buf;
+ dma_addr_t dma_addr;
+@@ -508,14 +509,18 @@ error_ready_state:
+ }
+
+ error_fw_load:
+- mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR;
+- wake_up_all(&mhi_cntrl->state_event);
++ write_lock_irq(&mhi_cntrl->pm_lock);
++ new_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_FW_DL_ERR);
++ write_unlock_irq(&mhi_cntrl->pm_lock);
++ if (new_state == MHI_PM_FW_DL_ERR)
++ wake_up_all(&mhi_cntrl->state_event);
+ }
+
+ int mhi_download_amss_image(struct mhi_controller *mhi_cntrl)
+ {
+ struct image_info *image_info = mhi_cntrl->fbc_image;
+ struct device *dev = &mhi_cntrl->mhi_dev->dev;
++ enum mhi_pm_state new_state;
+ int ret;
+
+ if (!image_info)
+@@ -526,8 +531,11 @@ int mhi_download_amss_image(struct mhi_c
+ &image_info->mhi_buf[image_info->entries - 1]);
+ if (ret) {
+ dev_err(dev, "MHI did not load AMSS, ret:%d\n", ret);
+- mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR;
+- wake_up_all(&mhi_cntrl->state_event);
++ write_lock_irq(&mhi_cntrl->pm_lock);
++ new_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_FW_DL_ERR);
++ write_unlock_irq(&mhi_cntrl->pm_lock);
++ if (new_state == MHI_PM_FW_DL_ERR)
++ wake_up_all(&mhi_cntrl->state_event);
+ }
+
+ return ret;
--- /dev/null
+From aaf67de78807c59c35bafb5003d4fb457c764800 Mon Sep 17 00:00:00 2001
+From: Xiubo Li <xiubli@redhat.com>
+Date: Wed, 19 Apr 2023 10:39:14 +0800
+Subject: ceph: fix potential use-after-free bug when trimming caps
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Xiubo Li <xiubli@redhat.com>
+
+commit aaf67de78807c59c35bafb5003d4fb457c764800 upstream.
+
+When trimming the caps and just after the 'session->s_cap_lock' is
+released in ceph_iterate_session_caps() the cap maybe removed by
+another thread, and when using the stale cap memory in the callbacks
+it will trigger use-after-free crash.
+
+We need to check the existence of the cap just after the 'ci->i_ceph_lock'
+being acquired. And do nothing if it's already removed.
+
+Cc: stable@vger.kernel.org
+Link: https://tracker.ceph.com/issues/43272
+Signed-off-by: Xiubo Li <xiubli@redhat.com>
+Reviewed-by: Luís Henriques <lhenriques@suse.de>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ceph/caps.c | 2 -
+ fs/ceph/debugfs.c | 16 +++++++----
+ fs/ceph/mds_client.c | 72 ++++++++++++++++++++++++++++++++-------------------
+ fs/ceph/mds_client.h | 3 --
+ fs/ceph/super.h | 2 +
+ 5 files changed, 61 insertions(+), 34 deletions(-)
+
+--- a/fs/ceph/caps.c
++++ b/fs/ceph/caps.c
+@@ -430,7 +430,7 @@ void ceph_reservation_status(struct ceph
+ *
+ * Called with i_ceph_lock held.
+ */
+-static struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci, int mds)
++struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci, int mds)
+ {
+ struct ceph_cap *cap;
+ struct rb_node *n = ci->i_caps.rb_node;
+--- a/fs/ceph/debugfs.c
++++ b/fs/ceph/debugfs.c
+@@ -248,14 +248,20 @@ static int metrics_caps_show(struct seq_
+ return 0;
+ }
+
+-static int caps_show_cb(struct inode *inode, struct ceph_cap *cap, void *p)
++static int caps_show_cb(struct inode *inode, int mds, void *p)
+ {
++ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct seq_file *s = p;
++ struct ceph_cap *cap;
+
+- seq_printf(s, "0x%-17llx%-3d%-17s%-17s\n", ceph_ino(inode),
+- cap->session->s_mds,
+- ceph_cap_string(cap->issued),
+- ceph_cap_string(cap->implemented));
++ spin_lock(&ci->i_ceph_lock);
++ cap = __get_cap_for_mds(ci, mds);
++ if (cap)
++ seq_printf(s, "0x%-17llx%-3d%-17s%-17s\n", ceph_ino(inode),
++ cap->session->s_mds,
++ ceph_cap_string(cap->issued),
++ ceph_cap_string(cap->implemented));
++ spin_unlock(&ci->i_ceph_lock);
+ return 0;
+ }
+
+--- a/fs/ceph/mds_client.c
++++ b/fs/ceph/mds_client.c
+@@ -1632,8 +1632,8 @@ static void cleanup_session_requests(str
+ * Caller must hold session s_mutex.
+ */
+ int ceph_iterate_session_caps(struct ceph_mds_session *session,
+- int (*cb)(struct inode *, struct ceph_cap *,
+- void *), void *arg)
++ int (*cb)(struct inode *, int mds, void *),
++ void *arg)
+ {
+ struct list_head *p;
+ struct ceph_cap *cap;
+@@ -1645,6 +1645,8 @@ int ceph_iterate_session_caps(struct cep
+ spin_lock(&session->s_cap_lock);
+ p = session->s_caps.next;
+ while (p != &session->s_caps) {
++ int mds;
++
+ cap = list_entry(p, struct ceph_cap, session_caps);
+ inode = igrab(&cap->ci->netfs.inode);
+ if (!inode) {
+@@ -1652,6 +1654,7 @@ int ceph_iterate_session_caps(struct cep
+ continue;
+ }
+ session->s_cap_iterator = cap;
++ mds = cap->mds;
+ spin_unlock(&session->s_cap_lock);
+
+ if (last_inode) {
+@@ -1663,7 +1666,7 @@ int ceph_iterate_session_caps(struct cep
+ old_cap = NULL;
+ }
+
+- ret = cb(inode, cap, arg);
++ ret = cb(inode, mds, arg);
+ last_inode = inode;
+
+ spin_lock(&session->s_cap_lock);
+@@ -1696,20 +1699,25 @@ out:
+ return ret;
+ }
+
+-static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
+- void *arg)
++static int remove_session_caps_cb(struct inode *inode, int mds, void *arg)
+ {
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ bool invalidate = false;
+- int iputs;
++ struct ceph_cap *cap;
++ int iputs = 0;
+
+- dout("removing cap %p, ci is %p, inode is %p\n",
+- cap, ci, &ci->netfs.inode);
+ spin_lock(&ci->i_ceph_lock);
+- iputs = ceph_purge_inode_cap(inode, cap, &invalidate);
++ cap = __get_cap_for_mds(ci, mds);
++ if (cap) {
++ dout(" removing cap %p, ci is %p, inode is %p\n",
++ cap, ci, &ci->netfs.inode);
++
++ iputs = ceph_purge_inode_cap(inode, cap, &invalidate);
++ }
+ spin_unlock(&ci->i_ceph_lock);
+
+- wake_up_all(&ci->i_cap_wq);
++ if (cap)
++ wake_up_all(&ci->i_cap_wq);
+ if (invalidate)
+ ceph_queue_invalidate(inode);
+ while (iputs--)
+@@ -1780,8 +1788,7 @@ enum {
+ *
+ * caller must hold s_mutex.
+ */
+-static int wake_up_session_cb(struct inode *inode, struct ceph_cap *cap,
+- void *arg)
++static int wake_up_session_cb(struct inode *inode, int mds, void *arg)
+ {
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ unsigned long ev = (unsigned long)arg;
+@@ -1792,12 +1799,14 @@ static int wake_up_session_cb(struct ino
+ ci->i_requested_max_size = 0;
+ spin_unlock(&ci->i_ceph_lock);
+ } else if (ev == RENEWCAPS) {
+- if (cap->cap_gen < atomic_read(&cap->session->s_cap_gen)) {
+- /* mds did not re-issue stale cap */
+- spin_lock(&ci->i_ceph_lock);
++ struct ceph_cap *cap;
++
++ spin_lock(&ci->i_ceph_lock);
++ cap = __get_cap_for_mds(ci, mds);
++ /* mds did not re-issue stale cap */
++ if (cap && cap->cap_gen < atomic_read(&cap->session->s_cap_gen))
+ cap->issued = cap->implemented = CEPH_CAP_PIN;
+- spin_unlock(&ci->i_ceph_lock);
+- }
++ spin_unlock(&ci->i_ceph_lock);
+ } else if (ev == FORCE_RO) {
+ }
+ wake_up_all(&ci->i_cap_wq);
+@@ -1959,16 +1968,22 @@ out:
+ * Yes, this is a bit sloppy. Our only real goal here is to respond to
+ * memory pressure from the MDS, though, so it needn't be perfect.
+ */
+-static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
++static int trim_caps_cb(struct inode *inode, int mds, void *arg)
+ {
+ int *remaining = arg;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ int used, wanted, oissued, mine;
++ struct ceph_cap *cap;
+
+ if (*remaining <= 0)
+ return -1;
+
+ spin_lock(&ci->i_ceph_lock);
++ cap = __get_cap_for_mds(ci, mds);
++ if (!cap) {
++ spin_unlock(&ci->i_ceph_lock);
++ return 0;
++ }
+ mine = cap->issued | cap->implemented;
+ used = __ceph_caps_used(ci);
+ wanted = __ceph_caps_file_wanted(ci);
+@@ -3911,26 +3926,22 @@ out_unlock:
+ /*
+ * Encode information about a cap for a reconnect with the MDS.
+ */
+-static int reconnect_caps_cb(struct inode *inode, struct ceph_cap *cap,
+- void *arg)
++static int reconnect_caps_cb(struct inode *inode, int mds, void *arg)
+ {
+ union {
+ struct ceph_mds_cap_reconnect v2;
+ struct ceph_mds_cap_reconnect_v1 v1;
+ } rec;
+- struct ceph_inode_info *ci = cap->ci;
++ struct ceph_inode_info *ci = ceph_inode(inode);
+ struct ceph_reconnect_state *recon_state = arg;
+ struct ceph_pagelist *pagelist = recon_state->pagelist;
+ struct dentry *dentry;
++ struct ceph_cap *cap;
+ char *path;
+- int pathlen = 0, err;
++ int pathlen = 0, err = 0;
+ u64 pathbase;
+ u64 snap_follows;
+
+- dout(" adding %p ino %llx.%llx cap %p %lld %s\n",
+- inode, ceph_vinop(inode), cap, cap->cap_id,
+- ceph_cap_string(cap->issued));
+-
+ dentry = d_find_primary(inode);
+ if (dentry) {
+ /* set pathbase to parent dir when msg_version >= 2 */
+@@ -3947,6 +3958,15 @@ static int reconnect_caps_cb(struct inod
+ }
+
+ spin_lock(&ci->i_ceph_lock);
++ cap = __get_cap_for_mds(ci, mds);
++ if (!cap) {
++ spin_unlock(&ci->i_ceph_lock);
++ goto out_err;
++ }
++ dout(" adding %p ino %llx.%llx cap %p %lld %s\n",
++ inode, ceph_vinop(inode), cap, cap->cap_id,
++ ceph_cap_string(cap->issued));
++
+ cap->seq = 0; /* reset cap seq */
+ cap->issue_seq = 0; /* and issue_seq */
+ cap->mseq = 0; /* and migrate_seq */
+--- a/fs/ceph/mds_client.h
++++ b/fs/ceph/mds_client.h
+@@ -541,8 +541,7 @@ extern void ceph_flush_cap_releases(stru
+ extern void ceph_queue_cap_reclaim_work(struct ceph_mds_client *mdsc);
+ extern void ceph_reclaim_caps_nr(struct ceph_mds_client *mdsc, int nr);
+ extern int ceph_iterate_session_caps(struct ceph_mds_session *session,
+- int (*cb)(struct inode *,
+- struct ceph_cap *, void *),
++ int (*cb)(struct inode *, int mds, void *),
+ void *arg);
+ extern void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc);
+
+--- a/fs/ceph/super.h
++++ b/fs/ceph/super.h
+@@ -1192,6 +1192,8 @@ extern void ceph_kick_flushing_caps(stru
+ struct ceph_mds_session *session);
+ void ceph_kick_flushing_inode_caps(struct ceph_mds_session *session,
+ struct ceph_inode_info *ci);
++extern struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci,
++ int mds);
+ extern struct ceph_cap *ceph_get_cap_for_mds(struct ceph_inode_info *ci,
+ int mds);
+ extern void ceph_take_cap_refs(struct ceph_inode_info *ci, int caps,
--- /dev/null
+From 7701c8bef4f14bd9f7940c6ed0e6a73584115a96 Mon Sep 17 00:00:00 2001
+From: Dan Williams <dan.j.williams@intel.com>
+Date: Fri, 14 Apr 2023 11:53:55 -0700
+Subject: cxl/hdm: Fail upon detecting 0-sized decoders
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+commit 7701c8bef4f14bd9f7940c6ed0e6a73584115a96 upstream.
+
+Decoders committed with 0-size lead to later crashes on shutdown as
+__cxl_dpa_release() assumes a 'struct resource' has been established in
+the in 'cxlds->dpa_res'. Just fail the driver load in this instance
+since there are deeper problems with the enumeration or the setup when
+this happens.
+
+Fixes: 9c57cde0dcbd ("cxl/hdm: Enumerate allocated DPA")
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Alison Schofield <alison.schofield@intel.com>
+Link: https://lore.kernel.org/r/168149843516.792294.11872242648319572632.stgit@dwillia2-xfh.jf.intel.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/cxl/core/hdm.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+--- a/drivers/cxl/core/hdm.c
++++ b/drivers/cxl/core/hdm.c
+@@ -219,8 +219,11 @@ static int __cxl_dpa_reserve(struct cxl_
+
+ lockdep_assert_held_write(&cxl_dpa_rwsem);
+
+- if (!len)
+- goto success;
++ if (!len) {
++ dev_warn(dev, "decoder%d.%d: empty reservation attempted\n",
++ port->id, cxled->cxld.id);
++ return -EINVAL;
++ }
+
+ if (cxled->dpa_res) {
+ dev_dbg(dev, "decoder%d.%d: existing allocation %pr assigned\n",
+@@ -273,7 +276,6 @@ static int __cxl_dpa_reserve(struct cxl_
+ cxled->mode = CXL_DECODER_MIXED;
+ }
+
+-success:
+ port->hdm_end++;
+ get_device(&cxled->cxld.dev);
+ return 0;
+@@ -732,6 +734,13 @@ static int init_hdm_decoder(struct cxl_p
+ port->id, cxld->id);
+ return -ENXIO;
+ }
++
++ if (size == 0) {
++ dev_warn(&port->dev,
++ "decoder%d.%d: Committed with zero size\n",
++ port->id, cxld->id);
++ return -ENXIO;
++ }
+ port->commit_end = cxld->id;
+ } else {
+ /* unless / until type-2 drivers arrive, assume type-3 */
--- /dev/null
+From a034c1370ded2ae6cbdc73a78241b3ed98c86d3d Mon Sep 17 00:00:00 2001
+From: Alexander Aring <aahringo@redhat.com>
+Date: Mon, 6 Mar 2023 15:48:08 -0500
+Subject: fs: dlm: fix DLM_IFL_CB_PENDING gets overwritten
+
+From: Alexander Aring <aahringo@redhat.com>
+
+commit a034c1370ded2ae6cbdc73a78241b3ed98c86d3d upstream.
+
+This patch introduce a new internal flag per lkb value to handle
+internal flags which are handled not on wire. The current lkb internal
+flags stored as lkb->lkb_flags are split in upper and lower bits, the
+lower bits are used to share internal flags over wire for other cluster
+wide lkb copies on other nodes.
+
+In commit 61bed0baa4db ("fs: dlm: use a non-static queue for callbacks")
+we introduced a new internal flag for pending callbacks for the dlm
+callback queue. This flag is protected by the lkb->lkb_cb_lock lock.
+This patch overlooked that on dlm receive path and the mentioned upper
+and lower bits, that dlm will read the flags, mask it and write it
+back. As example receive_flags() in fs/dlm/lock.c. This flag
+manipulation is not done atomically and is not protected by
+lkb->lkb_cb_lock. This has unknown side effects of the current callback
+handling.
+
+In future we should move to set/clear/test bit functionality and avoid
+read, mask and writing back flag values. In later patches we will move
+the upper parts to the new introduced internal lkb flags which are not
+shared between other cluster nodes to the new non shared internal flag
+field to avoid similar issues.
+
+Cc: stable@vger.kernel.org
+Fixes: 61bed0baa4db ("fs: dlm: use a non-static queue for callbacks")
+Reported-by: Bob Peterson <rpeterso@redhat.com>
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/dlm/ast.c | 9 ++++-----
+ fs/dlm/dlm_internal.h | 5 ++++-
+ fs/dlm/user.c | 2 +-
+ 3 files changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/fs/dlm/ast.c b/fs/dlm/ast.c
+index 26fef9945cc9..39805aea3336 100644
+--- a/fs/dlm/ast.c
++++ b/fs/dlm/ast.c
+@@ -45,7 +45,7 @@ void dlm_purge_lkb_callbacks(struct dlm_lkb *lkb)
+ kref_put(&cb->ref, dlm_release_callback);
+ }
+
+- lkb->lkb_flags &= ~DLM_IFL_CB_PENDING;
++ clear_bit(DLM_IFL_CB_PENDING_BIT, &lkb->lkb_iflags);
+
+ /* invalidate */
+ dlm_callback_set_last_ptr(&lkb->lkb_last_cast, NULL);
+@@ -103,10 +103,9 @@ int dlm_enqueue_lkb_callback(struct dlm_lkb *lkb, uint32_t flags, int mode,
+ cb->sb_status = status;
+ cb->sb_flags = (sbflags & 0x000000FF);
+ kref_init(&cb->ref);
+- if (!(lkb->lkb_flags & DLM_IFL_CB_PENDING)) {
+- lkb->lkb_flags |= DLM_IFL_CB_PENDING;
++ if (!test_and_set_bit(DLM_IFL_CB_PENDING_BIT, &lkb->lkb_iflags))
+ rv = DLM_ENQUEUE_CALLBACK_NEED_SCHED;
+- }
++
+ list_add_tail(&cb->list, &lkb->lkb_callbacks);
+
+ if (flags & DLM_CB_CAST)
+@@ -209,7 +208,7 @@ void dlm_callback_work(struct work_struct *work)
+ spin_lock(&lkb->lkb_cb_lock);
+ rv = dlm_dequeue_lkb_callback(lkb, &cb);
+ if (rv == DLM_DEQUEUE_CALLBACK_EMPTY) {
+- lkb->lkb_flags &= ~DLM_IFL_CB_PENDING;
++ clear_bit(DLM_IFL_CB_PENDING_BIT, &lkb->lkb_iflags);
+ spin_unlock(&lkb->lkb_cb_lock);
+ break;
+ }
+diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h
+index ab1a55337a6e..9bf70962bc49 100644
+--- a/fs/dlm/dlm_internal.h
++++ b/fs/dlm/dlm_internal.h
+@@ -211,7 +211,9 @@ struct dlm_args {
+ #endif
+ #define DLM_IFL_DEADLOCK_CANCEL 0x01000000
+ #define DLM_IFL_STUB_MS 0x02000000 /* magic number for m_flags */
+-#define DLM_IFL_CB_PENDING 0x04000000
++
++#define DLM_IFL_CB_PENDING_BIT 0
++
+ /* least significant 2 bytes are message changed, they are full transmitted
+ * but at receive side only the 2 bytes LSB will be set.
+ *
+@@ -246,6 +248,7 @@ struct dlm_lkb {
+ uint32_t lkb_exflags; /* external flags from caller */
+ uint32_t lkb_sbflags; /* lksb flags */
+ uint32_t lkb_flags; /* internal flags */
++ unsigned long lkb_iflags; /* internal flags */
+ uint32_t lkb_lvbseq; /* lvb sequence number */
+
+ int8_t lkb_status; /* granted, waiting, convert */
+diff --git a/fs/dlm/user.c b/fs/dlm/user.c
+index 35129505ddda..688a480879e4 100644
+--- a/fs/dlm/user.c
++++ b/fs/dlm/user.c
+@@ -884,7 +884,7 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count,
+ goto try_another;
+ case DLM_DEQUEUE_CALLBACK_LAST:
+ list_del_init(&lkb->lkb_cb_list);
+- lkb->lkb_flags &= ~DLM_IFL_CB_PENDING;
++ clear_bit(DLM_IFL_CB_PENDING_BIT, &lkb->lkb_iflags);
+ break;
+ case DLM_DEQUEUE_CALLBACK_SUCCESS:
+ break;
+--
+2.40.1
+
--- /dev/null
+From 7d01cb27f6aebc54efbe28d8961a973b8f795b13 Mon Sep 17 00:00:00 2001
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+Date: Wed, 1 Mar 2023 20:29:18 +0800
+Subject: Revert "ubifs: dirty_cow_znode: Fix memleak in error handling path"
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+commit 7d01cb27f6aebc54efbe28d8961a973b8f795b13 upstream.
+
+This reverts commit 122deabfe1428 (ubifs: dirty_cow_znode: Fix memleak
+in error handling path).
+After commit 122deabfe1428 applied, if insert_old_idx() failed, old
+index neither exists in TNC nor in old-index tree. Which means that
+old index node could be overwritten in layout_leb_in_gaps(), then
+ubifs image will be corrupted in power-cut.
+
+Fixes: 122deabfe1428 (ubifs: dirty_cow_znode: Fix memleak ... path)
+Cc: stable@vger.kernel.org
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ubifs/tnc.c | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+--- a/fs/ubifs/tnc.c
++++ b/fs/ubifs/tnc.c
+@@ -267,18 +267,11 @@ static struct ubifs_znode *dirty_cow_zno
+ if (zbr->len) {
+ err = insert_old_idx(c, zbr->lnum, zbr->offs);
+ if (unlikely(err))
+- /*
+- * Obsolete znodes will be freed by tnc_destroy_cnext()
+- * or free_obsolete_znodes(), copied up znodes should
+- * be added back to tnc and freed by
+- * ubifs_destroy_tnc_subtree().
+- */
+- goto out;
++ return ERR_PTR(err);
+ err = add_idx_dirt(c, zbr->lnum, zbr->len);
+ } else
+ err = 0;
+
+-out:
+ zbr->znode = zn;
+ zbr->lnum = 0;
+ zbr->offs = 0;
drm-amd-pm-re-enable-the-gfx-imu-when-smu-resume.patch
iommu-amd-fix-guest-virtual-apic-table-root-pointer-configuration-in-irte.patch
risc-v-align-sbi-probe-implementation-with-spec.patch
+revert-ubifs-dirty_cow_znode-fix-memleak-in-error-handling-path.patch
+ubifs-fix-memleak-when-insert_old_idx-failed.patch
+ubi-fix-return-value-overwrite-issue-in-try_write_vid_and_data.patch
+ubifs-free-memory-for-tmpfile-name.patch
+ubifs-fix-memory-leak-in-do_rename.patch
+ceph-fix-potential-use-after-free-bug-when-trimming-caps.patch
+fs-dlm-fix-dlm_ifl_cb_pending-gets-overwritten.patch
+xfs-don-t-consider-future-format-versions-valid.patch
+cxl-hdm-fail-upon-detecting-0-sized-decoders.patch
+bus-mhi-host-remove-duplicate-ee-check-for-syserr.patch
+bus-mhi-host-use-mhi_tryset_pm_state-for-setting-fw-error-state.patch
+bus-mhi-host-range-check-chdboff-and-erdboff.patch
+asoc-dt-bindings-qcom-lpass-rx-macro-correct-minitems-for-clocks.patch
--- /dev/null
+From 31a149d5c13c4cbcf97de3435817263a2d8c9d6e Mon Sep 17 00:00:00 2001
+From: Wang YanQing <udknight@gmail.com>
+Date: Tue, 28 Mar 2023 23:35:34 +0800
+Subject: ubi: Fix return value overwrite issue in try_write_vid_and_data()
+
+From: Wang YanQing <udknight@gmail.com>
+
+commit 31a149d5c13c4cbcf97de3435817263a2d8c9d6e upstream.
+
+The commit 2d78aee426d8 ("UBI: simplify LEB write and atomic LEB change code")
+adds helper function, try_write_vid_and_data(), to simplify the code, but this
+helper function has bug, it will return 0 (success) when ubi_io_write_vid_hdr()
+or the ubi_io_write_data() return error number (-EIO, etc), because the return
+value of ubi_wl_put_peb() will overwrite the original return value.
+
+This issue will cause unexpected data loss issue, because the caller of this
+function and UBIFS willn't know the data is lost.
+
+Fixes: 2d78aee426d8 ("UBI: simplify LEB write and atomic LEB change code")
+Cc: stable@vger.kernel.org
+Signed-off-by: Wang YanQing <udknight@gmail.com>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mtd/ubi/eba.c | 19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+--- a/drivers/mtd/ubi/eba.c
++++ b/drivers/mtd/ubi/eba.c
+@@ -946,7 +946,7 @@ static int try_write_vid_and_data(struct
+ int offset, int len)
+ {
+ struct ubi_device *ubi = vol->ubi;
+- int pnum, opnum, err, vol_id = vol->vol_id;
++ int pnum, opnum, err, err2, vol_id = vol->vol_id;
+
+ pnum = ubi_wl_get_peb(ubi);
+ if (pnum < 0) {
+@@ -981,10 +981,19 @@ static int try_write_vid_and_data(struct
+ out_put:
+ up_read(&ubi->fm_eba_sem);
+
+- if (err && pnum >= 0)
+- err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1);
+- else if (!err && opnum >= 0)
+- err = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0);
++ if (err && pnum >= 0) {
++ err2 = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1);
++ if (err2) {
++ ubi_warn(ubi, "failed to return physical eraseblock %d, error %d",
++ pnum, err2);
++ }
++ } else if (!err && opnum >= 0) {
++ err2 = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0);
++ if (err2) {
++ ubi_warn(ubi, "failed to return physical eraseblock %d, error %d",
++ opnum, err2);
++ }
++ }
+
+ return err;
+ }
--- /dev/null
+From b5fda08ef213352ac2df7447611eb4d383cce929 Mon Sep 17 00:00:00 2001
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+Date: Wed, 1 Mar 2023 20:29:19 +0800
+Subject: ubifs: Fix memleak when insert_old_idx() failed
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+commit b5fda08ef213352ac2df7447611eb4d383cce929 upstream.
+
+Following process will cause a memleak for copied up znode:
+
+dirty_cow_znode
+ zn = copy_znode(c, znode);
+ err = insert_old_idx(c, zbr->lnum, zbr->offs);
+ if (unlikely(err))
+ return ERR_PTR(err); // No one refers to zn.
+
+Fetch a reproducer in [Link].
+
+Function copy_znode() is split into 2 parts: resource allocation
+and znode replacement, insert_old_idx() is split in similar way,
+so resource cleanup could be done in error handling path without
+corrupting metadata(mem & disk).
+It's okay that old index inserting is put behind of add_idx_dirt(),
+old index is used in layout_leb_in_gaps(), so the two processes do
+not depend on each other.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216705
+Fixes: 1e51764a3c2a ("UBIFS: add new flash file system")
+Cc: stable@vger.kernel.org
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ubifs/tnc.c | 137 ++++++++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 87 insertions(+), 50 deletions(-)
+
+--- a/fs/ubifs/tnc.c
++++ b/fs/ubifs/tnc.c
+@@ -44,6 +44,33 @@ enum {
+ NOT_ON_MEDIA = 3,
+ };
+
++static void do_insert_old_idx(struct ubifs_info *c,
++ struct ubifs_old_idx *old_idx)
++{
++ struct ubifs_old_idx *o;
++ struct rb_node **p, *parent = NULL;
++
++ p = &c->old_idx.rb_node;
++ while (*p) {
++ parent = *p;
++ o = rb_entry(parent, struct ubifs_old_idx, rb);
++ if (old_idx->lnum < o->lnum)
++ p = &(*p)->rb_left;
++ else if (old_idx->lnum > o->lnum)
++ p = &(*p)->rb_right;
++ else if (old_idx->offs < o->offs)
++ p = &(*p)->rb_left;
++ else if (old_idx->offs > o->offs)
++ p = &(*p)->rb_right;
++ else {
++ ubifs_err(c, "old idx added twice!");
++ kfree(old_idx);
++ }
++ }
++ rb_link_node(&old_idx->rb, parent, p);
++ rb_insert_color(&old_idx->rb, &c->old_idx);
++}
++
+ /**
+ * insert_old_idx - record an index node obsoleted since the last commit start.
+ * @c: UBIFS file-system description object
+@@ -69,35 +96,15 @@ enum {
+ */
+ static int insert_old_idx(struct ubifs_info *c, int lnum, int offs)
+ {
+- struct ubifs_old_idx *old_idx, *o;
+- struct rb_node **p, *parent = NULL;
++ struct ubifs_old_idx *old_idx;
+
+ old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS);
+ if (unlikely(!old_idx))
+ return -ENOMEM;
+ old_idx->lnum = lnum;
+ old_idx->offs = offs;
++ do_insert_old_idx(c, old_idx);
+
+- p = &c->old_idx.rb_node;
+- while (*p) {
+- parent = *p;
+- o = rb_entry(parent, struct ubifs_old_idx, rb);
+- if (lnum < o->lnum)
+- p = &(*p)->rb_left;
+- else if (lnum > o->lnum)
+- p = &(*p)->rb_right;
+- else if (offs < o->offs)
+- p = &(*p)->rb_left;
+- else if (offs > o->offs)
+- p = &(*p)->rb_right;
+- else {
+- ubifs_err(c, "old idx added twice!");
+- kfree(old_idx);
+- return 0;
+- }
+- }
+- rb_link_node(&old_idx->rb, parent, p);
+- rb_insert_color(&old_idx->rb, &c->old_idx);
+ return 0;
+ }
+
+@@ -199,23 +206,6 @@ static struct ubifs_znode *copy_znode(st
+ __set_bit(DIRTY_ZNODE, &zn->flags);
+ __clear_bit(COW_ZNODE, &zn->flags);
+
+- ubifs_assert(c, !ubifs_zn_obsolete(znode));
+- __set_bit(OBSOLETE_ZNODE, &znode->flags);
+-
+- if (znode->level != 0) {
+- int i;
+- const int n = zn->child_cnt;
+-
+- /* The children now have new parent */
+- for (i = 0; i < n; i++) {
+- struct ubifs_zbranch *zbr = &zn->zbranch[i];
+-
+- if (zbr->znode)
+- zbr->znode->parent = zn;
+- }
+- }
+-
+- atomic_long_inc(&c->dirty_zn_cnt);
+ return zn;
+ }
+
+@@ -234,6 +224,42 @@ static int add_idx_dirt(struct ubifs_inf
+ }
+
+ /**
++ * replace_znode - replace old znode with new znode.
++ * @c: UBIFS file-system description object
++ * @new_zn: new znode
++ * @old_zn: old znode
++ * @zbr: the branch of parent znode
++ *
++ * Replace old znode with new znode in TNC.
++ */
++static void replace_znode(struct ubifs_info *c, struct ubifs_znode *new_zn,
++ struct ubifs_znode *old_zn, struct ubifs_zbranch *zbr)
++{
++ ubifs_assert(c, !ubifs_zn_obsolete(old_zn));
++ __set_bit(OBSOLETE_ZNODE, &old_zn->flags);
++
++ if (old_zn->level != 0) {
++ int i;
++ const int n = new_zn->child_cnt;
++
++ /* The children now have new parent */
++ for (i = 0; i < n; i++) {
++ struct ubifs_zbranch *child = &new_zn->zbranch[i];
++
++ if (child->znode)
++ child->znode->parent = new_zn;
++ }
++ }
++
++ zbr->znode = new_zn;
++ zbr->lnum = 0;
++ zbr->offs = 0;
++ zbr->len = 0;
++
++ atomic_long_inc(&c->dirty_zn_cnt);
++}
++
++/**
+ * dirty_cow_znode - ensure a znode is not being committed.
+ * @c: UBIFS file-system description object
+ * @zbr: branch of znode to check
+@@ -265,21 +291,32 @@ static struct ubifs_znode *dirty_cow_zno
+ return zn;
+
+ if (zbr->len) {
+- err = insert_old_idx(c, zbr->lnum, zbr->offs);
+- if (unlikely(err))
+- return ERR_PTR(err);
++ struct ubifs_old_idx *old_idx;
++
++ old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS);
++ if (unlikely(!old_idx)) {
++ err = -ENOMEM;
++ goto out;
++ }
++ old_idx->lnum = zbr->lnum;
++ old_idx->offs = zbr->offs;
++
+ err = add_idx_dirt(c, zbr->lnum, zbr->len);
+- } else
+- err = 0;
++ if (err) {
++ kfree(old_idx);
++ goto out;
++ }
+
+- zbr->znode = zn;
+- zbr->lnum = 0;
+- zbr->offs = 0;
+- zbr->len = 0;
++ do_insert_old_idx(c, old_idx);
++ }
++
++ replace_znode(c, zn, znode, zbr);
+
+- if (unlikely(err))
+- return ERR_PTR(err);
+ return zn;
++
++out:
++ kfree(zn);
++ return ERR_PTR(err);
+ }
+
+ /**
--- /dev/null
+From 3a36d20e012903f45714df2731261fdefac900cb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?M=C3=A5rten=20Lindahl?= <marten.lindahl@axis.com>
+Date: Thu, 30 Mar 2023 16:40:59 +0200
+Subject: ubifs: Fix memory leak in do_rename
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mårten Lindahl <marten.lindahl@axis.com>
+
+commit 3a36d20e012903f45714df2731261fdefac900cb upstream.
+
+If renaming a file in an encrypted directory, function
+fscrypt_setup_filename allocates memory for a file name. This name is
+never used, and before returning to the caller the memory for it is not
+freed.
+
+When running kmemleak on it we see that it is registered as a leak. The
+report below is triggered by a simple program 'rename' that renames a
+file in an encrypted directory:
+
+ unreferenced object 0xffff888101502840 (size 32):
+ comm "rename", pid 9404, jiffies 4302582475 (age 435.735s)
+ backtrace:
+ __kmem_cache_alloc_node
+ __kmalloc
+ fscrypt_setup_filename
+ do_rename
+ ubifs_rename
+ vfs_rename
+ do_renameat2
+
+To fix this we can remove the call to fscrypt_setup_filename as it's not
+needed.
+
+Fixes: 278d9a243635f26 ("ubifs: Rename whiteout atomically")
+Reported-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ubifs/dir.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+--- a/fs/ubifs/dir.c
++++ b/fs/ubifs/dir.c
+@@ -358,7 +358,6 @@ static struct inode *create_whiteout(str
+ umode_t mode = S_IFCHR | WHITEOUT_MODE;
+ struct inode *inode;
+ struct ubifs_info *c = dir->i_sb->s_fs_info;
+- struct fscrypt_name nm;
+
+ /*
+ * Create an inode('nlink = 1') for whiteout without updating journal,
+@@ -369,10 +368,6 @@ static struct inode *create_whiteout(str
+ dbg_gen("dent '%pd', mode %#hx in dir ino %lu",
+ dentry, mode, dir->i_ino);
+
+- err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm);
+- if (err)
+- return ERR_PTR(err);
+-
+ inode = ubifs_new_inode(c, dir, mode, false);
+ if (IS_ERR(inode)) {
+ err = PTR_ERR(inode);
+@@ -395,7 +390,6 @@ out_inode:
+ make_bad_inode(inode);
+ iput(inode);
+ out_free:
+- fscrypt_free_filename(&nm);
+ ubifs_err(c, "cannot create whiteout file, error %d", err);
+ return ERR_PTR(err);
+ }
--- /dev/null
+From 1fb815b38bb31d6af9bd0540b8652a0d6fe6cfd3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?M=C3=A5rten=20Lindahl?= <marten.lindahl@axis.com>
+Date: Thu, 30 Mar 2023 11:32:14 +0200
+Subject: ubifs: Free memory for tmpfile name
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mårten Lindahl <marten.lindahl@axis.com>
+
+commit 1fb815b38bb31d6af9bd0540b8652a0d6fe6cfd3 upstream.
+
+When opening a ubifs tmpfile on an encrypted directory, function
+fscrypt_setup_filename allocates memory for the name that is to be
+stored in the directory entry, but after the name has been copied to the
+directory entry inode, the memory is not freed.
+
+When running kmemleak on it we see that it is registered as a leak. The
+report below is triggered by a simple program 'tmpfile' just opening a
+tmpfile:
+
+ unreferenced object 0xffff88810178f380 (size 32):
+ comm "tmpfile", pid 509, jiffies 4294934744 (age 1524.742s)
+ backtrace:
+ __kmem_cache_alloc_node
+ __kmalloc
+ fscrypt_setup_filename
+ ubifs_tmpfile
+ vfs_tmpfile
+ path_openat
+
+Free this memory after it has been copied to the inode.
+
+Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ubifs/dir.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/ubifs/dir.c
++++ b/fs/ubifs/dir.c
+@@ -492,6 +492,7 @@ static int ubifs_tmpfile(struct user_nam
+ unlock_2_inodes(dir, inode);
+
+ ubifs_release_budget(c, &req);
++ fscrypt_free_filename(&nm);
+
+ return finish_open_simple(file, 0);
+
--- /dev/null
+From aa88019851a85df80cb77f143758b13aee09e3d9 Mon Sep 17 00:00:00 2001
+From: Dave Chinner <dchinner@redhat.com>
+Date: Wed, 12 Apr 2023 15:48:50 +1000
+Subject: xfs: don't consider future format versions valid
+
+From: Dave Chinner <dchinner@redhat.com>
+
+commit aa88019851a85df80cb77f143758b13aee09e3d9 upstream.
+
+In commit fe08cc504448 we reworked the valid superblock version
+checks. If it is a V5 filesystem, it is always valid, then we
+checked if the version was less than V4 (reject) and then checked
+feature fields in the V4 flags to determine if it was valid.
+
+What we missed was that if the version is not V4 at this point,
+we shoudl reject the fs. i.e. the check current treats V6+
+filesystems as if it was a v4 filesystem. Fix this.
+
+cc: stable@vger.kernel.org
+Fixes: fe08cc504448 ("xfs: open code sb verifier feature checks")
+Signed-off-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Dave Chinner <david@fromorbit.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/libxfs/xfs_sb.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/fs/xfs/libxfs/xfs_sb.c
++++ b/fs/xfs/libxfs/xfs_sb.c
+@@ -72,7 +72,8 @@ xfs_sb_validate_v5_features(
+ }
+
+ /*
+- * We support all XFS versions newer than a v4 superblock with V2 directories.
++ * We current support XFS v5 formats with known features and v4 superblocks with
++ * at least V2 directories.
+ */
+ bool
+ xfs_sb_good_version(
+@@ -86,16 +87,16 @@ xfs_sb_good_version(
+ if (xfs_sb_is_v5(sbp))
+ return xfs_sb_validate_v5_features(sbp);
+
++ /* versions prior to v4 are not supported */
++ if (XFS_SB_VERSION_NUM(sbp) != XFS_SB_VERSION_4)
++ return false;
++
+ /* We must not have any unknown v4 feature bits set */
+ if ((sbp->sb_versionnum & ~XFS_SB_VERSION_OKBITS) ||
+ ((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) &&
+ (sbp->sb_features2 & ~XFS_SB_VERSION2_OKBITS)))
+ return false;
+
+- /* versions prior to v4 are not supported */
+- if (XFS_SB_VERSION_NUM(sbp) < XFS_SB_VERSION_4)
+- return false;
+-
+ /* V4 filesystems need v2 directories and unwritten extents */
+ if (!(sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT))
+ return false;