--- /dev/null
+From 4a020b0cf8aa8445d525054d02a4587b418d3b17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Jul 2023 18:47:29 +0200
+Subject: ASoC: fsl_spdif: Silence output on stop
+
+From: Matus Gajdos <matuszpd@gmail.com>
+
+[ Upstream commit 0e4c2b6b0c4a4b4014d9424c27e5e79d185229c5 ]
+
+Clear TX registers on stop to prevent the SPDIF interface from sending
+last written word over and over again.
+
+Fixes: a2388a498ad2 ("ASoC: fsl: Add S/PDIF CPU DAI driver")
+Signed-off-by: Matus Gajdos <matuszpd@gmail.com>
+Reviewed-by: Fabio Estevam <festevam@gmail.com>
+Link: https://lore.kernel.org/r/20230719164729.19969-1-matuszpd@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_spdif.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
+index 015c3708aa04e..3fd26f2cdd60f 100644
+--- a/sound/soc/fsl/fsl_spdif.c
++++ b/sound/soc/fsl/fsl_spdif.c
+@@ -751,6 +751,8 @@ static int fsl_spdif_trigger(struct snd_pcm_substream *substream,
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ regmap_update_bits(regmap, REG_SPDIF_SCR, dmaen, 0);
+ regmap_update_bits(regmap, REG_SPDIF_SIE, intr, 0);
++ regmap_write(regmap, REG_SPDIF_STL, 0x0);
++ regmap_write(regmap, REG_SPDIF_STR, 0x0);
+ break;
+ default:
+ return -EINVAL;
+--
+2.40.1
+
--- /dev/null
+From 6ded68f763d35a5dae34a4593d2b5c0c9a597e0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jul 2023 22:33:22 +0200
+Subject: ata: pata_ns87415: mark ns87560_tf_read static
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 3fc2febb0f8ffae354820c1772ec008733237cfa ]
+
+The global function triggers a warning because of the missing prototype
+
+drivers/ata/pata_ns87415.c:263:6: warning: no previous prototype for 'ns87560_tf_read' [-Wmissing-prototypes]
+ 263 | void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+
+There are no other references to this, so just make it static.
+
+Fixes: c4b5b7b6c4423 ("pata_ns87415: Initial cut at 87415/87560 IDE support")
+Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/pata_ns87415.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c
+index d60e1f69d7b02..c697219a61a2d 100644
+--- a/drivers/ata/pata_ns87415.c
++++ b/drivers/ata/pata_ns87415.c
+@@ -260,7 +260,7 @@ static u8 ns87560_check_status(struct ata_port *ap)
+ * LOCKING:
+ * Inherited from caller.
+ */
+-void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
++static void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+ {
+ struct ata_ioports *ioaddr = &ap->ioaddr;
+
+--
+2.40.1
+
--- /dev/null
+From 53c82383d95206893972df4c754f586206eee795 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 13:14:12 -0700
+Subject: block: Fix a source code comment in include/uapi/linux/blkzoned.h
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit e0933b526fbfd937c4a8f4e35fcdd49f0e22d411 ]
+
+Fix the symbolic names for zone conditions in the blkzoned.h header
+file.
+
+Cc: Hannes Reinecke <hare@suse.de>
+Cc: Damien Le Moal <dlemoal@kernel.org>
+Fixes: 6a0cb1bc106f ("block: Implement support for zoned block devices")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Link: https://lore.kernel.org/r/20230706201422.3987341-1-bvanassche@acm.org
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/blkzoned.h | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/include/uapi/linux/blkzoned.h b/include/uapi/linux/blkzoned.h
+index b80fcc9ea5257..f85743ef6e7d1 100644
+--- a/include/uapi/linux/blkzoned.h
++++ b/include/uapi/linux/blkzoned.h
+@@ -51,13 +51,13 @@ enum blk_zone_type {
+ *
+ * The Zone Condition state machine in the ZBC/ZAC standards maps the above
+ * deinitions as:
+- * - ZC1: Empty | BLK_ZONE_EMPTY
++ * - ZC1: Empty | BLK_ZONE_COND_EMPTY
+ * - ZC2: Implicit Open | BLK_ZONE_COND_IMP_OPEN
+ * - ZC3: Explicit Open | BLK_ZONE_COND_EXP_OPEN
+- * - ZC4: Closed | BLK_ZONE_CLOSED
+- * - ZC5: Full | BLK_ZONE_FULL
+- * - ZC6: Read Only | BLK_ZONE_READONLY
+- * - ZC7: Offline | BLK_ZONE_OFFLINE
++ * - ZC4: Closed | BLK_ZONE_COND_CLOSED
++ * - ZC5: Full | BLK_ZONE_COND_FULL
++ * - ZC6: Read Only | BLK_ZONE_COND_READONLY
++ * - ZC7: Offline | BLK_ZONE_COND_OFFLINE
+ *
+ * Conditions 0x5 to 0xC are reserved by the current ZBC/ZAC spec and should
+ * be considered invalid.
+--
+2.40.1
+
--- /dev/null
+From afcc716e06ca69e788292d73b1ada0f8c11567db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Jul 2023 02:31:45 -0700
+Subject: cxl/acpi: Fix a use-after-free in cxl_parse_cfmws()
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 4cf67d3cc9994a59cf77bb9c0ccf9007fe916afe ]
+
+KASAN and KFENCE detected an user-after-free in the CXL driver. This
+happens in the cxl_decoder_add() fail path. KASAN prints the following
+error:
+
+ BUG: KASAN: slab-use-after-free in cxl_parse_cfmws (drivers/cxl/acpi.c:299)
+
+This happens in cxl_parse_cfmws(), where put_device() is called,
+releasing cxld, which is accessed later.
+
+Use the local variables in the dev_err() instead of pointing to the
+released memory. Since the dev_err() is printing a resource, change the open
+coded print format to use the %pr format specifier.
+
+Fixes: e50fe01e1f2a ("cxl/core: Drop ->platform_res attribute for root decoders")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Link: https://lore.kernel.org/r/20230714093146.2253438-1-leitao@debian.org
+Reviewed-by: Alison Schofield <alison.schofield@intel.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/acpi.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c
+index 7e1765b09e04a..973d6747078c9 100644
+--- a/drivers/cxl/acpi.c
++++ b/drivers/cxl/acpi.c
+@@ -296,8 +296,7 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg,
+ else
+ rc = cxl_decoder_autoremove(dev, cxld);
+ if (rc) {
+- dev_err(dev, "Failed to add decode range [%#llx - %#llx]\n",
+- cxld->hpa_range.start, cxld->hpa_range.end);
++ dev_err(dev, "Failed to add decode range: %pr", res);
+ return 0;
+ }
+ dev_dbg(dev, "add: %s node: %d range [%#llx - %#llx]\n",
+--
+2.40.1
+
--- /dev/null
+From 3e22534e52306665ac1573b6c8b6f826be5dd47f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Jul 2023 02:31:46 -0700
+Subject: cxl/acpi: Return 'rc' instead of '0' in cxl_parse_cfmws()
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 91019b5bc7c2c5e6f676cce80ee6d12b2753d018 ]
+
+Driver initialization returned success (return 0) even if the
+initialization (cxl_decoder_add() or acpi_table_parse_cedt()) failed.
+
+Return the error instead of swallowing it.
+
+Fixes: f4ce1f766f1e ("cxl/acpi: Convert CFMWS parsing to ACPI sub-table helpers")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Link: https://lore.kernel.org/r/20230714093146.2253438-2-leitao@debian.org
+Reviewed-by: Alison Schofield <alison.schofield@intel.com>
+Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/acpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c
+index 973d6747078c9..8757bf886207b 100644
+--- a/drivers/cxl/acpi.c
++++ b/drivers/cxl/acpi.c
+@@ -297,7 +297,7 @@ static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg,
+ rc = cxl_decoder_autoremove(dev, cxld);
+ if (rc) {
+ dev_err(dev, "Failed to add decode range: %pr", res);
+- return 0;
++ return rc;
+ }
+ dev_dbg(dev, "add: %s node: %d range [%#llx - %#llx]\n",
+ dev_name(&cxld->dev),
+--
+2.40.1
+
--- /dev/null
+From 240ca0dac958df3ef69b829bb3bc370edf1cc63e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Jul 2023 17:21:52 +0800
+Subject: dm raid: clean up four equivalent goto tags in raid_ctr()
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit e74c874eabe2e9173a8fbdad616cd89c70eb8ffd ]
+
+There are four equivalent goto tags in raid_ctr(), clean them up to
+use just one.
+
+There is no functional change and this is preparation to fix
+raid_ctr()'s unprotected md_stop().
+
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Stable-dep-of: 7d5fff8982a2 ("dm raid: protect md_stop() with 'reconfig_mutex'")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-raid.c | 27 +++++++++------------------
+ 1 file changed, 9 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
+index 85221a94c2073..156d44f690096 100644
+--- a/drivers/md/dm-raid.c
++++ b/drivers/md/dm-raid.c
+@@ -3251,8 +3251,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+ r = md_start(&rs->md);
+ if (r) {
+ ti->error = "Failed to start raid array";
+- mddev_unlock(&rs->md);
+- goto bad_md_start;
++ goto bad_unlock;
+ }
+
+ /* If raid4/5/6 journal mode explicitly requested (only possible with journal dev) -> set it */
+@@ -3260,8 +3259,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+ r = r5c_journal_mode_set(&rs->md, rs->journal_dev.mode);
+ if (r) {
+ ti->error = "Failed to set raid4/5/6 journal mode";
+- mddev_unlock(&rs->md);
+- goto bad_journal_mode_set;
++ goto bad_unlock;
+ }
+ }
+
+@@ -3271,19 +3269,15 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+ /* Try to adjust the raid4/5/6 stripe cache size to the stripe size */
+ if (rs_is_raid456(rs)) {
+ r = rs_set_raid456_stripe_cache(rs);
+- if (r) {
+- mddev_unlock(&rs->md);
+- goto bad_stripe_cache;
+- }
++ if (r)
++ goto bad_unlock;
+ }
+
+ /* Now do an early reshape check */
+ if (test_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags)) {
+ r = rs_check_reshape(rs);
+- if (r) {
+- mddev_unlock(&rs->md);
+- goto bad_check_reshape;
+- }
++ if (r)
++ goto bad_unlock;
+
+ /* Restore new, ctr requested layout to perform check */
+ rs_config_restore(rs, &rs_layout);
+@@ -3292,8 +3286,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+ r = rs->md.pers->check_reshape(&rs->md);
+ if (r) {
+ ti->error = "Reshape check failed";
+- mddev_unlock(&rs->md);
+- goto bad_check_reshape;
++ goto bad_unlock;
+ }
+ }
+ }
+@@ -3304,10 +3297,8 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+ mddev_unlock(&rs->md);
+ return 0;
+
+-bad_md_start:
+-bad_journal_mode_set:
+-bad_stripe_cache:
+-bad_check_reshape:
++bad_unlock:
++ mddev_unlock(&rs->md);
+ md_stop(&rs->md);
+ bad:
+ raid_set_free(rs);
+--
+2.40.1
+
--- /dev/null
+From e319a059d3f903393af2557cc7f75d6ac4643647 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Jul 2023 17:21:51 +0800
+Subject: dm raid: fix missing reconfig_mutex unlock in raid_ctr() error paths
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit bae3028799dc4f1109acc4df37c8ff06f2d8f1a0 ]
+
+In the error paths 'bad_stripe_cache' and 'bad_check_reshape',
+'reconfig_mutex' is still held after raid_ctr() returns.
+
+Fixes: 9dbd1aa3a81c ("dm raid: add reshaping support to the target")
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-raid.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
+index c8821fcb82998..85221a94c2073 100644
+--- a/drivers/md/dm-raid.c
++++ b/drivers/md/dm-raid.c
+@@ -3271,15 +3271,19 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+ /* Try to adjust the raid4/5/6 stripe cache size to the stripe size */
+ if (rs_is_raid456(rs)) {
+ r = rs_set_raid456_stripe_cache(rs);
+- if (r)
++ if (r) {
++ mddev_unlock(&rs->md);
+ goto bad_stripe_cache;
++ }
+ }
+
+ /* Now do an early reshape check */
+ if (test_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags)) {
+ r = rs_check_reshape(rs);
+- if (r)
++ if (r) {
++ mddev_unlock(&rs->md);
+ goto bad_check_reshape;
++ }
+
+ /* Restore new, ctr requested layout to perform check */
+ rs_config_restore(rs, &rs_layout);
+@@ -3288,6 +3292,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+ r = rs->md.pers->check_reshape(&rs->md);
+ if (r) {
+ ti->error = "Reshape check failed";
++ mddev_unlock(&rs->md);
+ goto bad_check_reshape;
+ }
+ }
+--
+2.40.1
+
--- /dev/null
+From b706750eaf5d01c65f2bc5cdd45a82ccff7b6c81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Jul 2023 17:21:53 +0800
+Subject: dm raid: protect md_stop() with 'reconfig_mutex'
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 7d5fff8982a2199d49ec067818af7d84d4f95ca0 ]
+
+__md_stop_writes() and __md_stop() will modify many fields that are
+protected by 'reconfig_mutex', and all the callers will grab
+'reconfig_mutex' except for md_stop().
+
+Also, update md_stop() to make certain 'reconfig_mutex' is held using
+lockdep_assert_held().
+
+Fixes: 9d09e663d550 ("dm: raid456 basic support")
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-raid.c | 4 +++-
+ drivers/md/md.c | 2 ++
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
+index 156d44f690096..de3dd6e6bb892 100644
+--- a/drivers/md/dm-raid.c
++++ b/drivers/md/dm-raid.c
+@@ -3298,8 +3298,8 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+ return 0;
+
+ bad_unlock:
+- mddev_unlock(&rs->md);
+ md_stop(&rs->md);
++ mddev_unlock(&rs->md);
+ bad:
+ raid_set_free(rs);
+
+@@ -3310,7 +3310,9 @@ static void raid_dtr(struct dm_target *ti)
+ {
+ struct raid_set *rs = ti->private;
+
++ mddev_lock_nointr(&rs->md);
+ md_stop(&rs->md);
++ mddev_unlock(&rs->md);
+ raid_set_free(rs);
+ }
+
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 18384251399ab..32d7ba8069aef 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -6260,6 +6260,8 @@ static void __md_stop(struct mddev *mddev)
+
+ void md_stop(struct mddev *mddev)
+ {
++ lockdep_assert_held(&mddev->reconfig_mutex);
++
+ /* stop the array and free an attached data structures.
+ * This is called from dm-raid
+ */
+--
+2.40.1
+
--- /dev/null
+From 7caf588dd7d44facb74958da28bc1ebf8ad3077c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jul 2023 17:55:49 +0300
+Subject: drm/amd/display: Unlock on error path in
+ dm_handle_mst_sideband_msg_ready_event()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 38ac4e8385ffb275b1837986ca6c16f26ea028c5 ]
+
+This error path needs to unlock the "aconnector->handle_mst_msg_ready"
+mutex before returning.
+
+Fixes: 4f6d9e38c4d2 ("drm/amd/display: Add polling method to handle MST reply packet")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+index 888e80f498e97..9bc86deac9e8e 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+@@ -706,7 +706,7 @@ void dm_handle_mst_sideband_msg_ready_event(
+
+ if (retry == 3) {
+ DRM_ERROR("Failed to ack MST event.\n");
+- return;
++ break;
+ }
+
+ drm_dp_mst_hpd_irq_send_new_request(&aconnector->mst_mgr);
+--
+2.40.1
+
--- /dev/null
+From 8212a9472e7df12a3e89c8c95f4581bbede6b336 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Jul 2023 00:14:59 -0500
+Subject: drm/amd: Fix an error handling mistake in psp_sw_init()
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit c01aebeef3ce45f696ffa0a1303cea9b34babb45 ]
+
+If the second call to amdgpu_bo_create_kernel() fails, the memory
+allocated from the first call should be cleared. If the third call
+fails, the memory from the second call should be cleared.
+
+Fixes: b95b5391684b ("drm/amdgpu/psp: move PSP memory alloc from hw_init to sw_init")
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+index e4757a2807d9a..db820331f2c61 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+@@ -491,11 +491,11 @@ static int psp_sw_init(void *handle)
+ return 0;
+
+ failed2:
+- amdgpu_bo_free_kernel(&psp->fw_pri_bo,
+- &psp->fw_pri_mc_addr, &psp->fw_pri_buf);
+-failed1:
+ amdgpu_bo_free_kernel(&psp->fence_buf_bo,
+ &psp->fence_buf_mc_addr, &psp->fence_buf);
++failed1:
++ amdgpu_bo_free_kernel(&psp->fw_pri_bo,
++ &psp->fw_pri_mc_addr, &psp->fw_pri_buf);
+ return ret;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 0d235c11f68c665ccf5582a3eee8c5f19845ee7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 20:49:31 +0200
+Subject: drm/i915: Fix an error handling path in igt_write_huge()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit e354f67733115b4453268f61e6e072e9b1ea7a2f ]
+
+All error handling paths go to 'out', except this one. Be consistent and
+also branch to 'out' here.
+
+Fixes: c10a652e239e ("drm/i915/selftests: Rework context handling in hugepages selftests")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com>
+Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
+Signed-off-by: Andi Shyti <andi.shyti@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/7a036b88671312ee9adc01c74ef5b3376f690b76.1689619758.git.christophe.jaillet@wanadoo.fr
+(cherry picked from commit 361ecaadb1ce3c5312c7c4c419271326d43899eb)
+Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+index 99f39a5feca15..e86e75971ec60 100644
+--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
++++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+@@ -1190,8 +1190,10 @@ static int igt_write_huge(struct drm_i915_private *i915,
+ * times in succession a possibility by enlarging the permutation array.
+ */
+ order = i915_random_order(count * count, &prng);
+- if (!order)
+- return -ENOMEM;
++ if (!order) {
++ err = -ENOMEM;
++ goto out;
++ }
+
+ max_page_size = rounddown_pow_of_two(obj->mm.page_sizes.sg);
+ max = div_u64(max - size, max_page_size);
+--
+2.40.1
+
--- /dev/null
+From 89452828fc9d42525ae8397b0d2b9617561ce68b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Jul 2023 10:54:07 -0700
+Subject: drm/msm/adreno: Fix snapshot BINDLESS_DATA size
+
+From: Rob Clark <robdclark@chromium.org>
+
+[ Upstream commit bd846ceee9c478d0397428f02696602ba5eb264a ]
+
+The incorrect size was causing "CP | AHB bus error" when snapshotting
+the GPU state on a6xx gen4 (a660 family).
+
+Closes: https://gitlab.freedesktop.org/drm/msm/-/issues/26
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Reviewed-by: Akhil P Oommen <quic_akhilpo@quicinc.com>
+Fixes: 1707add81551 ("drm/msm/a6xx: Add a6xx gpu state")
+Patchwork: https://patchwork.freedesktop.org/patch/546763/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h
+index 790f55e245332..e788ed72eb0d3 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h
+@@ -206,7 +206,7 @@ static const struct a6xx_shader_block {
+ SHADER(A6XX_SP_LB_3_DATA, 0x800),
+ SHADER(A6XX_SP_LB_4_DATA, 0x800),
+ SHADER(A6XX_SP_LB_5_DATA, 0x200),
+- SHADER(A6XX_SP_CB_BINDLESS_DATA, 0x2000),
++ SHADER(A6XX_SP_CB_BINDLESS_DATA, 0x800),
+ SHADER(A6XX_SP_CB_LEGACY_DATA, 0x280),
+ SHADER(A6XX_SP_UAV_DATA, 0x80),
+ SHADER(A6XX_SP_INST_TAG, 0x80),
+--
+2.40.1
+
--- /dev/null
+From 8ea4979926bde03ecddaaedd640e3fc928ce09b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jul 2023 13:30:21 -0700
+Subject: drm/msm: Disallow submit with fence id 0
+
+From: Rob Clark <robdclark@chromium.org>
+
+[ Upstream commit 1b5d0ddcb34a605835051ae2950d5cfed0373dd8 ]
+
+A fence id of zero is expected to be invalid, and is not removed from
+the fence_idr table. If userspace is requesting to specify the fence
+id with the FENCE_SN_IN flag, we need to reject a zero fence id value.
+
+Fixes: 17154addc5c1 ("drm/msm: Add MSM_SUBMIT_FENCE_SN_IN")
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Patchwork: https://patchwork.freedesktop.org/patch/549180/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/msm_gem_submit.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
+index 10cad7b99bac8..1bd78041b4d0d 100644
+--- a/drivers/gpu/drm/msm/msm_gem_submit.c
++++ b/drivers/gpu/drm/msm/msm_gem_submit.c
+@@ -902,7 +902,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+ * after the job is armed
+ */
+ if ((args->flags & MSM_SUBMIT_FENCE_SN_IN) &&
+- idr_find(&queue->fence_idr, args->fence)) {
++ (!args->fence || idr_find(&queue->fence_idr, args->fence))) {
+ spin_unlock(&queue->idr_lock);
+ idr_preload_end();
+ ret = -EINVAL;
+--
+2.40.1
+
--- /dev/null
+From 5db988d31bb7971cb749ccfa9180e1e6212a2782 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Jul 2023 12:01:04 -0400
+Subject: drm/msm/dpu: add missing flush and fetch bits for DMA4/DMA5 planes
+
+From: Jonathan Marek <jonathan@marek.ca>
+
+[ Upstream commit ba7a94ea73120e3f72c4a9b7ed6fd5598d29c069 ]
+
+Note that with this, DMA4/DMA5 are still non-functional, but at least
+display *something* in modetest instead of nothing or underflow.
+
+Fixes: efcd0107727c ("drm/msm/dpu: add support for SM8550")
+Signed-off-by: Jonathan Marek <jonathan@marek.ca>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
+Patchwork: https://patchwork.freedesktop.org/patch/545548/
+Link: https://lore.kernel.org/r/20230704160106.26055-1-jonathan@marek.ca
+Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+index f6270b7a0b140..5afbc16ec5bbb 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+@@ -51,7 +51,7 @@
+
+ static const u32 fetch_tbl[SSPP_MAX] = {CTL_INVALID_BIT, 16, 17, 18, 19,
+ CTL_INVALID_BIT, CTL_INVALID_BIT, CTL_INVALID_BIT, CTL_INVALID_BIT, 0,
+- 1, 2, 3, CTL_INVALID_BIT, CTL_INVALID_BIT};
++ 1, 2, 3, 4, 5};
+
+ static const struct dpu_ctl_cfg *_ctl_offset(enum dpu_ctl ctl,
+ const struct dpu_mdss_cfg *m,
+@@ -209,6 +209,12 @@ static void dpu_hw_ctl_update_pending_flush_sspp(struct dpu_hw_ctl *ctx,
+ case SSPP_DMA3:
+ ctx->pending_flush_mask |= BIT(25);
+ break;
++ case SSPP_DMA4:
++ ctx->pending_flush_mask |= BIT(13);
++ break;
++ case SSPP_DMA5:
++ ctx->pending_flush_mask |= BIT(14);
++ break;
+ case SSPP_CURSOR0:
+ ctx->pending_flush_mask |= BIT(22);
+ break;
+--
+2.40.1
+
--- /dev/null
+From f043d5ff8c32a0355c0bdf411686bbc32bb78c62 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 22:39:32 +0300
+Subject: drm/msm/dpu: drop enum dpu_core_perf_data_bus_id
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit e8383f5cf1b3573ce140a80bfbfd809278ab16d6 ]
+
+Drop the leftover of bus-client -> interconnect conversion, the enum
+dpu_core_perf_data_bus_id.
+
+Fixes: cb88482e2570 ("drm/msm/dpu: clean up references of DPU custom bus scaling")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/546048/
+Link: https://lore.kernel.org/r/20230707193942.3806526-2-dmitry.baryshkov@linaro.org
+Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h | 13 -------------
+ 1 file changed, 13 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
+index e3795995e1454..29bb8ee2bc266 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
+@@ -14,19 +14,6 @@
+
+ #define DPU_PERF_DEFAULT_MAX_CORE_CLK_RATE 412500000
+
+-/**
+- * enum dpu_core_perf_data_bus_id - data bus identifier
+- * @DPU_CORE_PERF_DATA_BUS_ID_MNOC: DPU/MNOC data bus
+- * @DPU_CORE_PERF_DATA_BUS_ID_LLCC: MNOC/LLCC data bus
+- * @DPU_CORE_PERF_DATA_BUS_ID_EBI: LLCC/EBI data bus
+- */
+-enum dpu_core_perf_data_bus_id {
+- DPU_CORE_PERF_DATA_BUS_ID_MNOC,
+- DPU_CORE_PERF_DATA_BUS_ID_LLCC,
+- DPU_CORE_PERF_DATA_BUS_ID_EBI,
+- DPU_CORE_PERF_DATA_BUS_ID_MAX,
+-};
+-
+ /**
+ * struct dpu_core_perf_params - definition of performance parameters
+ * @max_per_pipe_ib: maximum instantaneous bandwidth request
+--
+2.40.1
+
--- /dev/null
+From f6fdb07cc2b922495547d585c316700f24d9b742 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Jun 2023 22:14:16 +0200
+Subject: drm/msm/dsi: Drop unused regulators from QCM2290 14nm DSI PHY config
+
+From: Marijn Suijten <marijn.suijten@somainline.org>
+
+[ Upstream commit 97368254a08e2ca4766e7f84a45840230fe77fa3 ]
+
+The regulator setup was likely copied from other SoCs by mistake. Just
+like SM6125 the DSI PHY on this platform is not getting power from a
+regulator but from the MX power domain.
+
+Fixes: 572e9fd6d14a ("drm/msm/dsi: Add phy configuration for QCM2290")
+Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/544536/
+Link: https://lore.kernel.org/r/20230627-sm6125-dpu-v2-1-03e430a2078c@somainline.org
+Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
+index 3ce45b023e637..31deda1c664ad 100644
+--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
++++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
+@@ -1087,8 +1087,6 @@ const struct msm_dsi_phy_cfg dsi_phy_14nm_8953_cfgs = {
+
+ const struct msm_dsi_phy_cfg dsi_phy_14nm_2290_cfgs = {
+ .has_phy_lane = true,
+- .regulator_data = dsi_phy_14nm_17mA_regulators,
+- .num_regulators = ARRAY_SIZE(dsi_phy_14nm_17mA_regulators),
+ .ops = {
+ .enable = dsi_14nm_phy_enable,
+ .disable = dsi_14nm_phy_disable,
+--
+2.40.1
+
--- /dev/null
+From efb36738a671a194503abc80eeaf09607521be7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jul 2023 15:25:23 -0700
+Subject: drm/msm: Fix hw_fence error path cleanup
+
+From: Rob Clark <robdclark@chromium.org>
+
+[ Upstream commit 1cd0787f082e1a179f2b6e749d08daff1a9f6b1b ]
+
+In an error path where the submit is free'd without the job being run,
+the hw_fence pointer is simply a kzalloc'd block of memory. In this
+case we should just kfree() it, rather than trying to decrement it's
+reference count. Fortunately we can tell that this is the case by
+checking for a zero refcount, since if the job was run, the submit would
+be holding a reference to the hw_fence.
+
+Fixes: f94e6a51e17c ("drm/msm: Pre-allocate hw_fence")
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Patchwork: https://patchwork.freedesktop.org/patch/547088/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/msm_fence.c | 6 ++++++
+ drivers/gpu/drm/msm/msm_gem_submit.c | 14 +++++++++++++-
+ 2 files changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c
+index 96599ec3eb783..1a5d4f1c8b422 100644
+--- a/drivers/gpu/drm/msm/msm_fence.c
++++ b/drivers/gpu/drm/msm/msm_fence.c
+@@ -191,6 +191,12 @@ msm_fence_init(struct dma_fence *fence, struct msm_fence_context *fctx)
+
+ f->fctx = fctx;
+
++ /*
++ * Until this point, the fence was just some pre-allocated memory,
++ * no-one should have taken a reference to it yet.
++ */
++ WARN_ON(kref_read(&fence->refcount));
++
+ dma_fence_init(&f->base, &msm_fence_ops, &fctx->spinlock,
+ fctx->context, ++fctx->last_fence);
+ }
+diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
+index 9f5933c75e3df..10cad7b99bac8 100644
+--- a/drivers/gpu/drm/msm/msm_gem_submit.c
++++ b/drivers/gpu/drm/msm/msm_gem_submit.c
+@@ -86,7 +86,19 @@ void __msm_gem_submit_destroy(struct kref *kref)
+ }
+
+ dma_fence_put(submit->user_fence);
+- dma_fence_put(submit->hw_fence);
++
++ /*
++ * If the submit is freed before msm_job_run(), then hw_fence is
++ * just some pre-allocated memory, not a reference counted fence.
++ * Once the job runs and the hw_fence is initialized, it will
++ * have a refcount of at least one, since the submit holds a ref
++ * to the hw_fence.
++ */
++ if (kref_read(&submit->hw_fence->refcount) == 0) {
++ kfree(submit->hw_fence);
++ } else {
++ dma_fence_put(submit->hw_fence);
++ }
+
+ put_pid(submit->pid);
+ msm_submitqueue_put(submit->queue);
+--
+2.40.1
+
--- /dev/null
+From 85f727c8b2bd3b9309a9fc2542453c3024acf07a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 09:47:38 +0800
+Subject: drm/msm: Fix IS_ERR_OR_NULL() vs NULL check in a5xx_submit_in_rb()
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit 6e8a996563ecbe68e49c49abd4aaeef69f11f2dc ]
+
+The msm_gem_get_vaddr() returns an ERR_PTR() on failure, and a null
+is catastrophic here, so we should use IS_ERR_OR_NULL() to check
+the return value.
+
+Fixes: 6a8bd08d0465 ("drm/msm: add sudo flag to submit ioctl")
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Reviewed-by: Akhil P Oommen <quic_akhilpo@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/547712/
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+index a99310b687932..bbb1bf33f98ef 100644
+--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+@@ -89,7 +89,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit
+ * since we've already mapped it once in
+ * submit_reloc()
+ */
+- if (WARN_ON(!ptr))
++ if (WARN_ON(IS_ERR_OR_NULL(ptr)))
+ return;
+
+ for (i = 0; i < dwords; i++) {
+--
+2.40.1
+
--- /dev/null
+From fe38ecbcae8c5634eef8e68f8b829bdb0e15b13a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jul 2023 15:11:39 +0300
+Subject: drm/msm/mdss: correct UBWC programming for SM8550
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit a85c238c5ccd64f8d4c4560702c65cb25dee791c ]
+
+The SM8550 platform employs newer UBWC decoder, which requires slightly
+different programming.
+
+Fixes: a2f33995c19d ("drm/msm: mdss: add support for SM8550")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/546934/
+Link: https://lore.kernel.org/r/20230712121145.1994830-3-dmitry.baryshkov@linaro.org
+Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/msm_mdss.c | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c
+index e8c93731aaa18..4ae6fac20e48c 100644
+--- a/drivers/gpu/drm/msm/msm_mdss.c
++++ b/drivers/gpu/drm/msm/msm_mdss.c
+@@ -189,6 +189,7 @@ static int _msm_mdss_irq_domain_add(struct msm_mdss *msm_mdss)
+ #define UBWC_2_0 0x20000000
+ #define UBWC_3_0 0x30000000
+ #define UBWC_4_0 0x40000000
++#define UBWC_4_3 0x40030000
+
+ static void msm_mdss_setup_ubwc_dec_20(struct msm_mdss *msm_mdss)
+ {
+@@ -227,7 +228,10 @@ static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss *msm_mdss)
+ writel_relaxed(1, msm_mdss->mmio + UBWC_CTRL_2);
+ writel_relaxed(0, msm_mdss->mmio + UBWC_PREDICTION_MODE);
+ } else {
+- writel_relaxed(2, msm_mdss->mmio + UBWC_CTRL_2);
++ if (data->ubwc_dec_version == UBWC_4_3)
++ writel_relaxed(3, msm_mdss->mmio + UBWC_CTRL_2);
++ else
++ writel_relaxed(2, msm_mdss->mmio + UBWC_CTRL_2);
+ writel_relaxed(1, msm_mdss->mmio + UBWC_PREDICTION_MODE);
+ }
+ }
+@@ -271,6 +275,7 @@ static int msm_mdss_enable(struct msm_mdss *msm_mdss)
+ msm_mdss_setup_ubwc_dec_30(msm_mdss);
+ break;
+ case UBWC_4_0:
++ case UBWC_4_3:
+ msm_mdss_setup_ubwc_dec_40(msm_mdss);
+ break;
+ default:
+@@ -561,6 +566,16 @@ static const struct msm_mdss_data sm8250_data = {
+ .macrotile_mode = 1,
+ };
+
++static const struct msm_mdss_data sm8550_data = {
++ .ubwc_version = UBWC_4_0,
++ .ubwc_dec_version = UBWC_4_3,
++ .ubwc_swizzle = 6,
++ .ubwc_static = 1,
++ /* TODO: highest_bank_bit = 2 for LP_DDR4 */
++ .highest_bank_bit = 3,
++ .macrotile_mode = 1,
++};
++
+ static const struct of_device_id mdss_dt_match[] = {
+ { .compatible = "qcom,mdss" },
+ { .compatible = "qcom,msm8998-mdss" },
+@@ -575,7 +590,7 @@ static const struct of_device_id mdss_dt_match[] = {
+ { .compatible = "qcom,sm8250-mdss", .data = &sm8250_data },
+ { .compatible = "qcom,sm8350-mdss", .data = &sm8250_data },
+ { .compatible = "qcom,sm8450-mdss", .data = &sm8250_data },
+- { .compatible = "qcom,sm8550-mdss", .data = &sm8250_data },
++ { .compatible = "qcom,sm8550-mdss", .data = &sm8550_data },
+ {}
+ };
+ MODULE_DEVICE_TABLE(of, mdss_dt_match);
+--
+2.40.1
+
--- /dev/null
+From eeb6cae4b72849aea747b3845c16d229eb31a8d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Apr 2023 08:47:27 +0200
+Subject: fs/9p: Fix a datatype used with V9FS_DIRECT_IO
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 95f41d87810083d8b3dedcce46a4e356cf4a9673 ]
+
+The commit in Fixes has introduced some "enum p9_session_flags" values
+larger than a char.
+Such values are stored in "v9fs_session_info->flags" which is a char only.
+
+Turn it into an int so that the "enum p9_session_flags" values can fit in
+it.
+
+Fixes: 6deffc8924b5 ("fs/9p: Add new mount modes")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Dominique Martinet <asmadeus@codewreck.org>
+Reviewed-by: Christian Schoenebeck <linux_oss@crudebyte.com>
+Signed-off-by: Eric Van Hensbergen <ericvh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/9p/v9fs.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
+index 06a2514f0d882..698c43dd5dc86 100644
+--- a/fs/9p/v9fs.h
++++ b/fs/9p/v9fs.h
+@@ -108,7 +108,7 @@ enum p9_cache_bits {
+
+ struct v9fs_session_info {
+ /* options */
+- unsigned char flags;
++ unsigned int flags;
+ unsigned char nodev;
+ unsigned short debug;
+ unsigned int afid;
+--
+2.40.1
+
--- /dev/null
+From 428a0ff284c8422ad5680b7ad15d379aed378d46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 16:05:49 -0300
+Subject: iommufd: IOMMUFD_DESTROY should not increase the refcount
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit 99f98a7c0d6985d5507c8130a981972e4b7b3bdc ]
+
+syzkaller found a race where IOMMUFD_DESTROY increments the refcount:
+
+ obj = iommufd_get_object(ucmd->ictx, cmd->id, IOMMUFD_OBJ_ANY);
+ if (IS_ERR(obj))
+ return PTR_ERR(obj);
+ iommufd_ref_to_users(obj);
+ /* See iommufd_ref_to_users() */
+ if (!iommufd_object_destroy_user(ucmd->ictx, obj))
+
+As part of the sequence to join the two existing primitives together.
+
+Allowing the refcount the be elevated without holding the destroy_rwsem
+violates the assumption that all temporary refcount elevations are
+protected by destroy_rwsem. Racing IOMMUFD_DESTROY with
+iommufd_object_destroy_user() will cause spurious failures:
+
+ WARNING: CPU: 0 PID: 3076 at drivers/iommu/iommufd/device.c:477 iommufd_access_destroy+0x18/0x20 drivers/iommu/iommufd/device.c:478
+ Modules linked in:
+ CPU: 0 PID: 3076 Comm: syz-executor.0 Not tainted 6.3.0-rc1-syzkaller #0
+ Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/03/2023
+ RIP: 0010:iommufd_access_destroy+0x18/0x20 drivers/iommu/iommufd/device.c:477
+ Code: e8 3d 4e 00 00 84 c0 74 01 c3 0f 0b c3 0f 1f 44 00 00 f3 0f 1e fa 48 89 fe 48 8b bf a8 00 00 00 e8 1d 4e 00 00 84 c0 74 01 c3 <0f> 0b c3 0f 1f 44 00 00 41 57 41 56 41 55 4c 8d ae d0 00 00 00 41
+ RSP: 0018:ffffc90003067e08 EFLAGS: 00010246
+ RAX: 0000000000000000 RBX: ffff888109ea0300 RCX: 0000000000000000
+ RDX: 0000000000000001 RSI: 0000000000000000 RDI: 00000000ffffffff
+ RBP: 0000000000000004 R08: 0000000000000000 R09: ffff88810bbb3500
+ R10: ffff88810bbb3e48 R11: 0000000000000000 R12: ffffc90003067e88
+ R13: ffffc90003067ea8 R14: ffff888101249800 R15: 00000000fffffffe
+ FS: 00007ff7254fe6c0(0000) GS:ffff888237c00000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 0000555557262da8 CR3: 000000010a6fd000 CR4: 0000000000350ef0
+ Call Trace:
+ <TASK>
+ iommufd_test_create_access drivers/iommu/iommufd/selftest.c:596 [inline]
+ iommufd_test+0x71c/0xcf0 drivers/iommu/iommufd/selftest.c:813
+ iommufd_fops_ioctl+0x10f/0x1b0 drivers/iommu/iommufd/main.c:337
+ vfs_ioctl fs/ioctl.c:51 [inline]
+ __do_sys_ioctl fs/ioctl.c:870 [inline]
+ __se_sys_ioctl fs/ioctl.c:856 [inline]
+ __x64_sys_ioctl+0x84/0xc0 fs/ioctl.c:856
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x38/0x80 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+The solution is to not increment the refcount on the IOMMUFD_DESTROY path
+at all. Instead use the xa_lock to serialize everything. The refcount
+check == 1 and xa_erase can be done under a single critical region. This
+avoids the need for any refcount incrementing.
+
+It has the downside that if userspace races destroy with other operations
+it will get an EBUSY instead of waiting, but this is kind of racing is
+already dangerous.
+
+Fixes: 2ff4bed7fee7 ("iommufd: File descriptor, context, kconfig and makefiles")
+Link: https://lore.kernel.org/r/2-v1-85aacb2af554+bc-iommufd_syz3_jgg@nvidia.com
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Reported-by: syzbot+7574ebfe589049630608@syzkaller.appspotmail.com
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/iommufd/device.c | 12 +---
+ drivers/iommu/iommufd/iommufd_private.h | 15 ++++-
+ drivers/iommu/iommufd/main.c | 78 +++++++++++++++++++------
+ 3 files changed, 75 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c
+index 29d05663d4d17..ed2937a4e196f 100644
+--- a/drivers/iommu/iommufd/device.c
++++ b/drivers/iommu/iommufd/device.c
+@@ -109,10 +109,7 @@ EXPORT_SYMBOL_NS_GPL(iommufd_device_bind, IOMMUFD);
+ */
+ void iommufd_device_unbind(struct iommufd_device *idev)
+ {
+- bool was_destroyed;
+-
+- was_destroyed = iommufd_object_destroy_user(idev->ictx, &idev->obj);
+- WARN_ON(!was_destroyed);
++ iommufd_object_destroy_user(idev->ictx, &idev->obj);
+ }
+ EXPORT_SYMBOL_NS_GPL(iommufd_device_unbind, IOMMUFD);
+
+@@ -382,7 +379,7 @@ void iommufd_device_detach(struct iommufd_device *idev)
+ mutex_unlock(&hwpt->devices_lock);
+
+ if (hwpt->auto_domain)
+- iommufd_object_destroy_user(idev->ictx, &hwpt->obj);
++ iommufd_object_deref_user(idev->ictx, &hwpt->obj);
+ else
+ refcount_dec(&hwpt->obj.users);
+
+@@ -456,10 +453,7 @@ EXPORT_SYMBOL_NS_GPL(iommufd_access_create, IOMMUFD);
+ */
+ void iommufd_access_destroy(struct iommufd_access *access)
+ {
+- bool was_destroyed;
+-
+- was_destroyed = iommufd_object_destroy_user(access->ictx, &access->obj);
+- WARN_ON(!was_destroyed);
++ iommufd_object_destroy_user(access->ictx, &access->obj);
+ }
+ EXPORT_SYMBOL_NS_GPL(iommufd_access_destroy, IOMMUFD);
+
+diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h
+index b38e67d1988bd..f9790983699ce 100644
+--- a/drivers/iommu/iommufd/iommufd_private.h
++++ b/drivers/iommu/iommufd/iommufd_private.h
+@@ -176,8 +176,19 @@ void iommufd_object_abort_and_destroy(struct iommufd_ctx *ictx,
+ struct iommufd_object *obj);
+ void iommufd_object_finalize(struct iommufd_ctx *ictx,
+ struct iommufd_object *obj);
+-bool iommufd_object_destroy_user(struct iommufd_ctx *ictx,
+- struct iommufd_object *obj);
++void __iommufd_object_destroy_user(struct iommufd_ctx *ictx,
++ struct iommufd_object *obj, bool allow_fail);
++static inline void iommufd_object_destroy_user(struct iommufd_ctx *ictx,
++ struct iommufd_object *obj)
++{
++ __iommufd_object_destroy_user(ictx, obj, false);
++}
++static inline void iommufd_object_deref_user(struct iommufd_ctx *ictx,
++ struct iommufd_object *obj)
++{
++ __iommufd_object_destroy_user(ictx, obj, true);
++}
++
+ struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
+ size_t size,
+ enum iommufd_object_type type);
+diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c
+index 3fbe636c3d8a6..4cf5f73f27084 100644
+--- a/drivers/iommu/iommufd/main.c
++++ b/drivers/iommu/iommufd/main.c
+@@ -116,14 +116,56 @@ struct iommufd_object *iommufd_get_object(struct iommufd_ctx *ictx, u32 id,
+ return obj;
+ }
+
++/*
++ * Remove the given object id from the xarray if the only reference to the
++ * object is held by the xarray. The caller must call ops destroy().
++ */
++static struct iommufd_object *iommufd_object_remove(struct iommufd_ctx *ictx,
++ u32 id, bool extra_put)
++{
++ struct iommufd_object *obj;
++ XA_STATE(xas, &ictx->objects, id);
++
++ xa_lock(&ictx->objects);
++ obj = xas_load(&xas);
++ if (xa_is_zero(obj) || !obj) {
++ obj = ERR_PTR(-ENOENT);
++ goto out_xa;
++ }
++
++ /*
++ * If the caller is holding a ref on obj we put it here under the
++ * spinlock.
++ */
++ if (extra_put)
++ refcount_dec(&obj->users);
++
++ if (!refcount_dec_if_one(&obj->users)) {
++ obj = ERR_PTR(-EBUSY);
++ goto out_xa;
++ }
++
++ xas_store(&xas, NULL);
++ if (ictx->vfio_ioas == container_of(obj, struct iommufd_ioas, obj))
++ ictx->vfio_ioas = NULL;
++
++out_xa:
++ xa_unlock(&ictx->objects);
++
++ /* The returned object reference count is zero */
++ return obj;
++}
++
+ /*
+ * The caller holds a users refcount and wants to destroy the object. Returns
+ * true if the object was destroyed. In all cases the caller no longer has a
+ * reference on obj.
+ */
+-bool iommufd_object_destroy_user(struct iommufd_ctx *ictx,
+- struct iommufd_object *obj)
++void __iommufd_object_destroy_user(struct iommufd_ctx *ictx,
++ struct iommufd_object *obj, bool allow_fail)
+ {
++ struct iommufd_object *ret;
++
+ /*
+ * The purpose of the destroy_rwsem is to ensure deterministic
+ * destruction of objects used by external drivers and destroyed by this
+@@ -131,22 +173,22 @@ bool iommufd_object_destroy_user(struct iommufd_ctx *ictx,
+ * side of this, such as during ioctl execution.
+ */
+ down_write(&obj->destroy_rwsem);
+- xa_lock(&ictx->objects);
+- refcount_dec(&obj->users);
+- if (!refcount_dec_if_one(&obj->users)) {
+- xa_unlock(&ictx->objects);
+- up_write(&obj->destroy_rwsem);
+- return false;
+- }
+- __xa_erase(&ictx->objects, obj->id);
+- if (ictx->vfio_ioas && &ictx->vfio_ioas->obj == obj)
+- ictx->vfio_ioas = NULL;
+- xa_unlock(&ictx->objects);
++ ret = iommufd_object_remove(ictx, obj->id, true);
+ up_write(&obj->destroy_rwsem);
+
++ if (allow_fail && IS_ERR(ret))
++ return;
++
++ /*
++ * If there is a bug and we couldn't destroy the object then we did put
++ * back the caller's refcount and will eventually try to free it again
++ * during close.
++ */
++ if (WARN_ON(IS_ERR(ret)))
++ return;
++
+ iommufd_object_ops[obj->type].destroy(obj);
+ kfree(obj);
+- return true;
+ }
+
+ static int iommufd_destroy(struct iommufd_ucmd *ucmd)
+@@ -154,13 +196,11 @@ static int iommufd_destroy(struct iommufd_ucmd *ucmd)
+ struct iommu_destroy *cmd = ucmd->cmd;
+ struct iommufd_object *obj;
+
+- obj = iommufd_get_object(ucmd->ictx, cmd->id, IOMMUFD_OBJ_ANY);
++ obj = iommufd_object_remove(ucmd->ictx, cmd->id, false);
+ if (IS_ERR(obj))
+ return PTR_ERR(obj);
+- iommufd_ref_to_users(obj);
+- /* See iommufd_ref_to_users() */
+- if (!iommufd_object_destroy_user(ucmd->ictx, obj))
+- return -EBUSY;
++ iommufd_object_ops[obj->type].destroy(obj);
++ kfree(obj);
+ return 0;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 4448377acf69003a46261fe2f215d78257bdd5ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jun 2023 04:01:46 -0700
+Subject: RDMA/bnxt_re: add helper function __poll_for_resp
+
+From: Kashyap Desai <kashyap.desai@broadcom.com>
+
+[ Upstream commit 354f5bd985af9515190828bc642ebdf59acea121 ]
+
+This interface will be used if the driver has not enabled interrupt
+and/or interrupt is disabled for a short period of time.
+Completion is not possible from interrupt so this interface does
+self-polling.
+
+Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Link: https://lore.kernel.org/r/1686308514-11996-10-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: 29900bf351e1 ("RDMA/bnxt_re: Fix hang during driver unload")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 44 +++++++++++++++++++++-
+ drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 1 +
+ 2 files changed, 44 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+index f867507d427f9..0028043bb51cd 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+@@ -260,6 +260,44 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,
+ return 0;
+ }
+
++/**
++ * __poll_for_resp - self poll completion for rcfw command
++ * @rcfw - rcfw channel instance of rdev
++ * @cookie - cookie to track the command
++ * @opcode - rcfw submitted for given opcode
++ *
++ * It works same as __wait_for_resp except this function will
++ * do self polling in sort interval since interrupt is disabled.
++ * This function can not be called from non-sleepable context.
++ *
++ * Returns:
++ * -ETIMEOUT if command is not completed in specific time interval.
++ * 0 if command is completed by firmware.
++ */
++static int __poll_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie,
++ u8 opcode)
++{
++ struct bnxt_qplib_cmdq_ctx *cmdq = &rcfw->cmdq;
++ unsigned long issue_time;
++ u16 cbit;
++
++ cbit = cookie % rcfw->cmdq_depth;
++ issue_time = jiffies;
++
++ do {
++ if (test_bit(ERR_DEVICE_DETACHED, &cmdq->flags))
++ return bnxt_qplib_map_rc(opcode);
++
++ usleep_range(1000, 1001);
++
++ bnxt_qplib_service_creq(&rcfw->creq.creq_tasklet);
++ if (!test_bit(cbit, cmdq->cmdq_bitmap))
++ return 0;
++ if (jiffies_to_msecs(jiffies - issue_time) > 10000)
++ return -ETIMEDOUT;
++ } while (true);
++};
++
+ static int __send_message_basic_sanity(struct bnxt_qplib_rcfw *rcfw,
+ struct bnxt_qplib_cmdqmsg *msg)
+ {
+@@ -328,8 +366,10 @@ static int __bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
+
+ if (msg->block)
+ rc = __block_for_resp(rcfw, cookie, opcode);
+- else
++ else if (atomic_read(&rcfw->rcfw_intr_enabled))
+ rc = __wait_for_resp(rcfw, cookie, opcode);
++ else
++ rc = __poll_for_resp(rcfw, cookie, opcode);
+ if (rc) {
+ /* timed out */
+ dev_err(&rcfw->pdev->dev, "cmdq[%#x]=%#x timedout (%d)msec\n",
+@@ -798,6 +838,7 @@ void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill)
+ kfree(creq->irq_name);
+ creq->irq_name = NULL;
+ creq->requested = false;
++ atomic_set(&rcfw->rcfw_intr_enabled, 0);
+ }
+
+ void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw)
+@@ -859,6 +900,7 @@ int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector,
+ creq->requested = true;
+
+ bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, res->cctx, true);
++ atomic_inc(&rcfw->rcfw_intr_enabled);
+
+ return 0;
+ }
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
+index 43dc11febf46a..4608c0ef07a87 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
+@@ -225,6 +225,7 @@ struct bnxt_qplib_rcfw {
+ u64 oos_prev;
+ u32 init_oos_stats;
+ u32 cmdq_depth;
++ atomic_t rcfw_intr_enabled;
+ struct semaphore rcfw_inflight;
+ };
+
+--
+2.40.1
+
--- /dev/null
+From 15a3a71e5ca04ee2b1ab2e62f847209400a429e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jun 2023 04:01:43 -0700
+Subject: RDMA/bnxt_re: Avoid the command wait if firmware is inactive
+
+From: Kashyap Desai <kashyap.desai@broadcom.com>
+
+[ Upstream commit 3022cc15119733cebaef05feddb5d87b9e401c0e ]
+
+Add a check to avoid waiting if driver already detects a
+FW timeout. Return success for resource destroy in case
+the device is detached. Add helper function to map timeout
+error code to success.
+
+Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Link: https://lore.kernel.org/r/1686308514-11996-7-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: 29900bf351e1 ("RDMA/bnxt_re: Fix hang during driver unload")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 52 ++++++++++++++++++++--
+ 1 file changed, 48 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+index 918e588588885..bfa0f29c7abf4 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+@@ -53,10 +53,47 @@
+
+ static void bnxt_qplib_service_creq(struct tasklet_struct *t);
+
++/**
++ * bnxt_qplib_map_rc - map return type based on opcode
++ * @opcode - roce slow path opcode
++ *
++ * In some cases like firmware halt is detected, the driver is supposed to
++ * remap the error code of the timed out command.
++ *
++ * It is not safe to assume hardware is really inactive so certain opcodes
++ * like destroy qp etc are not safe to be returned success, but this function
++ * will be called when FW already reports a timeout. This would be possible
++ * only when FW crashes and resets. This will clear all the HW resources.
++ *
++ * Returns:
++ * 0 to communicate success to caller.
++ * Non zero error code to communicate failure to caller.
++ */
++static int bnxt_qplib_map_rc(u8 opcode)
++{
++ switch (opcode) {
++ case CMDQ_BASE_OPCODE_DESTROY_QP:
++ case CMDQ_BASE_OPCODE_DESTROY_SRQ:
++ case CMDQ_BASE_OPCODE_DESTROY_CQ:
++ case CMDQ_BASE_OPCODE_DEALLOCATE_KEY:
++ case CMDQ_BASE_OPCODE_DEREGISTER_MR:
++ case CMDQ_BASE_OPCODE_DELETE_GID:
++ case CMDQ_BASE_OPCODE_DESTROY_QP1:
++ case CMDQ_BASE_OPCODE_DESTROY_AH:
++ case CMDQ_BASE_OPCODE_DEINITIALIZE_FW:
++ case CMDQ_BASE_OPCODE_MODIFY_ROCE_CC:
++ case CMDQ_BASE_OPCODE_SET_LINK_AGGR_MODE:
++ return 0;
++ default:
++ return -ETIMEDOUT;
++ }
++}
++
+ /**
+ * __wait_for_resp - Don't hold the cpu context and wait for response
+ * @rcfw - rcfw channel instance of rdev
+ * @cookie - cookie to track the command
++ * @opcode - rcfw submitted for given opcode
+ *
+ * Wait for command completion in sleepable context.
+ *
+@@ -64,7 +101,7 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t);
+ * 0 if command is completed by firmware.
+ * Non zero error code for rest of the case.
+ */
+-static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
++static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie, u8 opcode)
+ {
+ struct bnxt_qplib_cmdq_ctx *cmdq;
+ u16 cbit;
+@@ -74,6 +111,9 @@ static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
+ cbit = cookie % rcfw->cmdq_depth;
+
+ do {
++ if (test_bit(ERR_DEVICE_DETACHED, &cmdq->flags))
++ return bnxt_qplib_map_rc(opcode);
++
+ /* Non zero means command completed */
+ ret = wait_event_timeout(cmdq->waitq,
+ !test_bit(cbit, cmdq->cmdq_bitmap),
+@@ -94,6 +134,7 @@ static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
+ * __block_for_resp - hold the cpu context and wait for response
+ * @rcfw - rcfw channel instance of rdev
+ * @cookie - cookie to track the command
++ * @opcode - rcfw submitted for given opcode
+ *
+ * This function will hold the cpu (non-sleepable context) and
+ * wait for command completion. Maximum holding interval is 8 second.
+@@ -102,7 +143,7 @@ static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
+ * -ETIMEOUT if command is not completed in specific time interval.
+ * 0 if command is completed by firmware.
+ */
+-static int __block_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
++static int __block_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie, u8 opcode)
+ {
+ struct bnxt_qplib_cmdq_ctx *cmdq = &rcfw->cmdq;
+ unsigned long issue_time = 0;
+@@ -112,6 +153,9 @@ static int __block_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
+ issue_time = jiffies;
+
+ do {
++ if (test_bit(ERR_DEVICE_DETACHED, &cmdq->flags))
++ return bnxt_qplib_map_rc(opcode);
++
+ udelay(1);
+
+ bnxt_qplib_service_creq(&rcfw->creq.creq_tasklet);
+@@ -267,9 +311,9 @@ int bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
+ } while (retry_cnt--);
+
+ if (msg->block)
+- rc = __block_for_resp(rcfw, cookie);
++ rc = __block_for_resp(rcfw, cookie, opcode);
+ else
+- rc = __wait_for_resp(rcfw, cookie);
++ rc = __wait_for_resp(rcfw, cookie, opcode);
+ if (rc) {
+ /* timed out */
+ dev_err(&rcfw->pdev->dev, "cmdq[%#x]=%#x timedout (%d)msec\n",
+--
+2.40.1
+
--- /dev/null
+From c7423534ba555e7cd7823b22a256536332186d1a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jun 2023 04:01:42 -0700
+Subject: RDMA/bnxt_re: Enhance the existing functions that wait for FW
+ responses
+
+From: Kashyap Desai <kashyap.desai@broadcom.com>
+
+[ Upstream commit 8cf1d12ad56beb73d2439ccf334b7148e71de58e ]
+
+Use jiffies based timewait instead of counting iteration for
+commands that block for FW response.
+
+Also add a poll routine for control path commands. This is for
+polling completion if the waiting commands timeout. This avoids cases
+where the driver misses completion interrupts.
+
+Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Link: https://lore.kernel.org/r/1686308514-11996-6-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: 29900bf351e1 ("RDMA/bnxt_re: Fix hang during driver unload")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 65 +++++++++++++++++-----
+ 1 file changed, 51 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+index c11b8e708844c..918e588588885 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+@@ -53,37 +53,74 @@
+
+ static void bnxt_qplib_service_creq(struct tasklet_struct *t);
+
+-/* Hardware communication channel */
++/**
++ * __wait_for_resp - Don't hold the cpu context and wait for response
++ * @rcfw - rcfw channel instance of rdev
++ * @cookie - cookie to track the command
++ *
++ * Wait for command completion in sleepable context.
++ *
++ * Returns:
++ * 0 if command is completed by firmware.
++ * Non zero error code for rest of the case.
++ */
+ static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
+ {
+ struct bnxt_qplib_cmdq_ctx *cmdq;
+ u16 cbit;
+- int rc;
++ int ret;
+
+ cmdq = &rcfw->cmdq;
+ cbit = cookie % rcfw->cmdq_depth;
+- rc = wait_event_timeout(cmdq->waitq,
+- !test_bit(cbit, cmdq->cmdq_bitmap),
+- msecs_to_jiffies(RCFW_CMD_WAIT_TIME_MS));
+- return rc ? 0 : -ETIMEDOUT;
++
++ do {
++ /* Non zero means command completed */
++ ret = wait_event_timeout(cmdq->waitq,
++ !test_bit(cbit, cmdq->cmdq_bitmap),
++ msecs_to_jiffies(10000));
++
++ if (!test_bit(cbit, cmdq->cmdq_bitmap))
++ return 0;
++
++ bnxt_qplib_service_creq(&rcfw->creq.creq_tasklet);
++
++ if (!test_bit(cbit, cmdq->cmdq_bitmap))
++ return 0;
++
++ } while (true);
+ };
+
++/**
++ * __block_for_resp - hold the cpu context and wait for response
++ * @rcfw - rcfw channel instance of rdev
++ * @cookie - cookie to track the command
++ *
++ * This function will hold the cpu (non-sleepable context) and
++ * wait for command completion. Maximum holding interval is 8 second.
++ *
++ * Returns:
++ * -ETIMEOUT if command is not completed in specific time interval.
++ * 0 if command is completed by firmware.
++ */
+ static int __block_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie)
+ {
+- u32 count = RCFW_BLOCKED_CMD_WAIT_COUNT;
+- struct bnxt_qplib_cmdq_ctx *cmdq;
++ struct bnxt_qplib_cmdq_ctx *cmdq = &rcfw->cmdq;
++ unsigned long issue_time = 0;
+ u16 cbit;
+
+- cmdq = &rcfw->cmdq;
+ cbit = cookie % rcfw->cmdq_depth;
+- if (!test_bit(cbit, cmdq->cmdq_bitmap))
+- goto done;
++ issue_time = jiffies;
++
+ do {
+ udelay(1);
++
+ bnxt_qplib_service_creq(&rcfw->creq.creq_tasklet);
+- } while (test_bit(cbit, cmdq->cmdq_bitmap) && --count);
+-done:
+- return count ? 0 : -ETIMEDOUT;
++ if (!test_bit(cbit, cmdq->cmdq_bitmap))
++ return 0;
++
++ } while (time_before(jiffies, issue_time + (8 * HZ)));
++
++ return -ETIMEDOUT;
+ };
+
+ static int __send_message(struct bnxt_qplib_rcfw *rcfw,
+--
+2.40.1
+
--- /dev/null
+From 9a727e5f479d10d2f56e49a8a03f3e574c934209 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Jul 2023 01:22:49 -0700
+Subject: RDMA/bnxt_re: Fix hang during driver unload
+
+From: Selvin Xavier <selvin.xavier@broadcom.com>
+
+[ Upstream commit 29900bf351e1a7e4643da5c3c3cd9df75c577b88 ]
+
+Driver unload hits a hang during stress testing of load/unload.
+
+stack trace snippet -
+
+tasklet_kill at ffffffff9aabb8b2
+bnxt_qplib_nq_stop_irq at ffffffffc0a805fb [bnxt_re]
+bnxt_qplib_disable_nq at ffffffffc0a80c5b [bnxt_re]
+bnxt_re_dev_uninit at ffffffffc0a67d15 [bnxt_re]
+bnxt_re_remove_device at ffffffffc0a6af1d [bnxt_re]
+
+tasklet_kill can hang if the tasklet is scheduled after it is disabled.
+
+Modified the sequences to disable the interrupt first and synchronize
+irq before disabling the tasklet.
+
+Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver")
+Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Link: https://lore.kernel.org/r/1689322969-25402-3-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/qplib_fp.c | 10 +++++-----
+ drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 9 ++++-----
+ 2 files changed, 9 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+index e589b04f953c5..b34cc500f51f3 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+@@ -420,19 +420,19 @@ void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill)
+ if (!nq->requested)
+ return;
+
+- tasklet_disable(&nq->nq_tasklet);
++ nq->requested = false;
+ /* Mask h/w interrupt */
+ bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, false);
+ /* Sync with last running IRQ handler */
+ synchronize_irq(nq->msix_vec);
+- if (kill)
+- tasklet_kill(&nq->nq_tasklet);
+-
+ irq_set_affinity_hint(nq->msix_vec, NULL);
+ free_irq(nq->msix_vec, nq);
+ kfree(nq->name);
+ nq->name = NULL;
+- nq->requested = false;
++
++ if (kill)
++ tasklet_kill(&nq->nq_tasklet);
++ tasklet_disable(&nq->nq_tasklet);
+ }
+
+ void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq)
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+index 0028043bb51cd..05683ce64887f 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+@@ -826,19 +826,18 @@ void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill)
+ if (!creq->requested)
+ return;
+
+- tasklet_disable(&creq->creq_tasklet);
++ creq->requested = false;
+ /* Mask h/w interrupts */
+ bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, false);
+ /* Sync with last running IRQ-handler */
+ synchronize_irq(creq->msix_vec);
+- if (kill)
+- tasklet_kill(&creq->creq_tasklet);
+-
+ free_irq(creq->msix_vec, rcfw);
+ kfree(creq->irq_name);
+ creq->irq_name = NULL;
+- creq->requested = false;
+ atomic_set(&rcfw->rcfw_intr_enabled, 0);
++ if (kill)
++ tasklet_kill(&creq->creq_tasklet);
++ tasklet_disable(&creq->creq_tasklet);
+ }
+
+ void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw)
+--
+2.40.1
+
--- /dev/null
+From b475fc524ebc5b9d32788fe5a02f38fda3398f7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Jul 2023 01:22:48 -0700
+Subject: RDMA/bnxt_re: Prevent handling any completions after qp destroy
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kashyap Desai <kashyap.desai@broadcom.com>
+
+[ Upstream commit b5bbc6551297447d3cca55cf907079e206e9cd82 ]
+
+HW may generate completions that indicates QP is destroyed.
+Driver should not be scheduling any more completion handlers
+for this QP, after the QP is destroyed. Since CQs are active
+during the QP destroy, driver may still schedule completion
+handlers. This can cause a race where the destroy_cq and poll_cq
+running simultaneously.
+
+Snippet of kernel panic while doing bnxt_re driver load unload in loop.
+This indicates a poll after the CQ is freed.Â
+
+[77786.481636] Call Trace:
+[77786.481640] Â <TASK>
+[77786.481644] Â bnxt_re_poll_cq+0x14a/0x620 [bnxt_re]
+[77786.481658] Â ? kvm_clock_read+0x14/0x30
+[77786.481693] Â __ib_process_cq+0x57/0x190 [ib_core]
+[77786.481728] Â ib_cq_poll_work+0x26/0x80 [ib_core]
+[77786.481761] Â process_one_work+0x1e5/0x3f0
+[77786.481768] Â worker_thread+0x50/0x3a0
+[77786.481785] Â ? __pfx_worker_thread+0x10/0x10
+[77786.481790] Â kthread+0xe2/0x110
+[77786.481794] Â ? __pfx_kthread+0x10/0x10
+[77786.481797] Â ret_from_fork+0x2c/0x50
+
+To avoid this, complete all completion handlers before returning the
+destroy QP. If free_cq is called soon after destroy_qp, IB stack
+will cancel the CQ work before invoking the destroy_cq verb and
+this will prevent any race mentioned.
+
+Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver")
+Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Link: https://lore.kernel.org/r/1689322969-25402-2-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/ib_verbs.c | 12 ++++++++++++
+ drivers/infiniband/hw/bnxt_re/qplib_fp.c | 18 ++++++++++++++++++
+ drivers/infiniband/hw/bnxt_re/qplib_fp.h | 1 +
+ 3 files changed, 31 insertions(+)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+index 952811c40c54b..ebe6852c40e8c 100644
+--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+@@ -797,7 +797,10 @@ static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp)
+ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
+ {
+ struct bnxt_re_qp *qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp);
++ struct bnxt_qplib_qp *qplib_qp = &qp->qplib_qp;
+ struct bnxt_re_dev *rdev = qp->rdev;
++ struct bnxt_qplib_nq *scq_nq = NULL;
++ struct bnxt_qplib_nq *rcq_nq = NULL;
+ unsigned int flags;
+ int rc;
+
+@@ -831,6 +834,15 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
+ ib_umem_release(qp->rumem);
+ ib_umem_release(qp->sumem);
+
++ /* Flush all the entries of notification queue associated with
++ * given qp.
++ */
++ scq_nq = qplib_qp->scq->nq;
++ rcq_nq = qplib_qp->rcq->nq;
++ bnxt_re_synchronize_nq(scq_nq);
++ if (scq_nq != rcq_nq)
++ bnxt_re_synchronize_nq(rcq_nq);
++
+ return 0;
+ }
+
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+index 55f092c2c8a88..e589b04f953c5 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+@@ -381,6 +381,24 @@ static void bnxt_qplib_service_nq(struct tasklet_struct *t)
+ spin_unlock_bh(&hwq->lock);
+ }
+
++/* bnxt_re_synchronize_nq - self polling notification queue.
++ * @nq - notification queue pointer
++ *
++ * This function will start polling entries of a given notification queue
++ * for all pending entries.
++ * This function is useful to synchronize notification entries while resources
++ * are going away.
++ */
++
++void bnxt_re_synchronize_nq(struct bnxt_qplib_nq *nq)
++{
++ int budget = nq->budget;
++
++ nq->budget = nq->hwq.max_elements;
++ bnxt_qplib_service_nq(&nq->nq_tasklet);
++ nq->budget = budget;
++}
++
+ static irqreturn_t bnxt_qplib_nq_irq(int irq, void *dev_instance)
+ {
+ struct bnxt_qplib_nq *nq = dev_instance;
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+index a42820821c473..404b851091ca2 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
++++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+@@ -553,6 +553,7 @@ int bnxt_qplib_process_flush_list(struct bnxt_qplib_cq *cq,
+ struct bnxt_qplib_cqe *cqe,
+ int num_cqes);
+ void bnxt_qplib_flush_cqn_wq(struct bnxt_qplib_qp *qp);
++void bnxt_re_synchronize_nq(struct bnxt_qplib_nq *nq);
+
+ static inline void *bnxt_qplib_get_swqe(struct bnxt_qplib_q *que, u32 *swq_idx)
+ {
+--
+2.40.1
+
--- /dev/null
+From 7b5004a286a2c307f4e198f87140414038e77e58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jun 2023 04:01:45 -0700
+Subject: RDMA/bnxt_re: Simplify the function that sends the FW commands
+
+From: Kashyap Desai <kashyap.desai@broadcom.com>
+
+[ Upstream commit 159cf95e42a7ca7375646fab82c0056cbb71f9e9 ]
+
+ - Use __send_message_basic_sanity helper function.
+ - Do not retry posting same command if there is a queue full detection.
+ - ENXIO is used to indicate controller recovery.
+ - In the case of ERR_DEVICE_DETACHED state, the driver should not post
+ commands to the firmware, but also return fabricated written code.
+
+Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Link: https://lore.kernel.org/r/1686308514-11996-9-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: 29900bf351e1 ("RDMA/bnxt_re: Fix hang during driver unload")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 125 +++++++++++----------
+ drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 22 ++++
+ 2 files changed, 86 insertions(+), 61 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+index 42484a1149c7c..f867507d427f9 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+@@ -170,34 +170,22 @@ static int __block_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie, u8 opcode)
+ static int __send_message(struct bnxt_qplib_rcfw *rcfw,
+ struct bnxt_qplib_cmdqmsg *msg)
+ {
+- struct bnxt_qplib_cmdq_ctx *cmdq = &rcfw->cmdq;
+- struct bnxt_qplib_hwq *hwq = &cmdq->hwq;
++ u32 bsize, opcode, free_slots, required_slots;
++ struct bnxt_qplib_cmdq_ctx *cmdq;
+ struct bnxt_qplib_crsqe *crsqe;
+ struct bnxt_qplib_cmdqe *cmdqe;
++ struct bnxt_qplib_hwq *hwq;
+ u32 sw_prod, cmdq_prod;
+ struct pci_dev *pdev;
+ unsigned long flags;
+- u32 bsize, opcode;
+ u16 cookie, cbit;
+ u8 *preq;
+
++ cmdq = &rcfw->cmdq;
++ hwq = &cmdq->hwq;
+ pdev = rcfw->pdev;
+
+ opcode = __get_cmdq_base_opcode(msg->req, msg->req_sz);
+- if (!test_bit(FIRMWARE_INITIALIZED_FLAG, &cmdq->flags) &&
+- (opcode != CMDQ_BASE_OPCODE_QUERY_FUNC &&
+- opcode != CMDQ_BASE_OPCODE_INITIALIZE_FW &&
+- opcode != CMDQ_BASE_OPCODE_QUERY_VERSION)) {
+- dev_err(&pdev->dev,
+- "RCFW not initialized, reject opcode 0x%x\n", opcode);
+- return -EINVAL;
+- }
+-
+- if (test_bit(FIRMWARE_INITIALIZED_FLAG, &cmdq->flags) &&
+- opcode == CMDQ_BASE_OPCODE_INITIALIZE_FW) {
+- dev_err(&pdev->dev, "RCFW already initialized!\n");
+- return -EINVAL;
+- }
+
+ if (test_bit(FIRMWARE_TIMED_OUT, &cmdq->flags))
+ return -ETIMEDOUT;
+@@ -206,40 +194,37 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,
+ * cmdqe
+ */
+ spin_lock_irqsave(&hwq->lock, flags);
+- if (msg->req->cmd_size >= HWQ_FREE_SLOTS(hwq)) {
+- dev_err(&pdev->dev, "RCFW: CMDQ is full!\n");
++ required_slots = bnxt_qplib_get_cmd_slots(msg->req);
++ free_slots = HWQ_FREE_SLOTS(hwq);
++ cookie = cmdq->seq_num & RCFW_MAX_COOKIE_VALUE;
++ cbit = cookie % rcfw->cmdq_depth;
++
++ if (required_slots >= free_slots ||
++ test_bit(cbit, cmdq->cmdq_bitmap)) {
++ dev_info_ratelimited(&pdev->dev,
++ "CMDQ is full req/free %d/%d!",
++ required_slots, free_slots);
+ spin_unlock_irqrestore(&hwq->lock, flags);
+ return -EAGAIN;
+ }
+-
+-
+- cookie = cmdq->seq_num & RCFW_MAX_COOKIE_VALUE;
+- cbit = cookie % rcfw->cmdq_depth;
+ if (msg->block)
+ cookie |= RCFW_CMD_IS_BLOCKING;
+-
+ set_bit(cbit, cmdq->cmdq_bitmap);
+ __set_cmdq_base_cookie(msg->req, msg->req_sz, cpu_to_le16(cookie));
+ crsqe = &rcfw->crsqe_tbl[cbit];
+- if (crsqe->resp) {
+- spin_unlock_irqrestore(&hwq->lock, flags);
+- return -EBUSY;
+- }
+-
+- /* change the cmd_size to the number of 16byte cmdq unit.
+- * req->cmd_size is modified here
+- */
+ bsize = bnxt_qplib_set_cmd_slots(msg->req);
+-
+- memset(msg->resp, 0, sizeof(*msg->resp));
++ crsqe->free_slots = free_slots;
+ crsqe->resp = (struct creq_qp_event *)msg->resp;
+ crsqe->resp->cookie = cpu_to_le16(cookie);
+ crsqe->req_size = __get_cmdq_base_cmd_size(msg->req, msg->req_sz);
+ if (__get_cmdq_base_resp_size(msg->req, msg->req_sz) && msg->sb) {
+ struct bnxt_qplib_rcfw_sbuf *sbuf = msg->sb;
+- __set_cmdq_base_resp_addr(msg->req, msg->req_sz, cpu_to_le64(sbuf->dma_addr));
++
++ __set_cmdq_base_resp_addr(msg->req, msg->req_sz,
++ cpu_to_le64(sbuf->dma_addr));
+ __set_cmdq_base_resp_size(msg->req, msg->req_sz,
+- ALIGN(sbuf->size, BNXT_QPLIB_CMDQE_UNITS));
++ ALIGN(sbuf->size,
++ BNXT_QPLIB_CMDQE_UNITS));
+ }
+
+ preq = (u8 *)msg->req;
+@@ -247,11 +232,6 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,
+ /* Locate the next cmdq slot */
+ sw_prod = HWQ_CMP(hwq->prod, hwq);
+ cmdqe = bnxt_qplib_get_qe(hwq, sw_prod, NULL);
+- if (!cmdqe) {
+- dev_err(&pdev->dev,
+- "RCFW request failed with no cmdqe!\n");
+- goto done;
+- }
+ /* Copy a segment of the req cmd to the cmdq */
+ memset(cmdqe, 0, sizeof(*cmdqe));
+ memcpy(cmdqe, preq, min_t(u32, bsize, sizeof(*cmdqe)));
+@@ -275,12 +255,43 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,
+ wmb();
+ writel(cmdq_prod, cmdq->cmdq_mbox.prod);
+ writel(RCFW_CMDQ_TRIG_VAL, cmdq->cmdq_mbox.db);
+-done:
+ spin_unlock_irqrestore(&hwq->lock, flags);
+ /* Return the CREQ response pointer */
+ return 0;
+ }
+
++static int __send_message_basic_sanity(struct bnxt_qplib_rcfw *rcfw,
++ struct bnxt_qplib_cmdqmsg *msg)
++{
++ struct bnxt_qplib_cmdq_ctx *cmdq;
++ u32 opcode;
++
++ cmdq = &rcfw->cmdq;
++ opcode = __get_cmdq_base_opcode(msg->req, msg->req_sz);
++
++ /* Prevent posting if f/w is not in a state to process */
++ if (test_bit(ERR_DEVICE_DETACHED, &rcfw->cmdq.flags))
++ return -ENXIO;
++
++ if (test_bit(FIRMWARE_INITIALIZED_FLAG, &cmdq->flags) &&
++ opcode == CMDQ_BASE_OPCODE_INITIALIZE_FW) {
++ dev_err(&rcfw->pdev->dev, "QPLIB: RCFW already initialized!");
++ return -EINVAL;
++ }
++
++ if (!test_bit(FIRMWARE_INITIALIZED_FLAG, &cmdq->flags) &&
++ (opcode != CMDQ_BASE_OPCODE_QUERY_FUNC &&
++ opcode != CMDQ_BASE_OPCODE_INITIALIZE_FW &&
++ opcode != CMDQ_BASE_OPCODE_QUERY_VERSION)) {
++ dev_err(&rcfw->pdev->dev,
++ "QPLIB: RCFW not initialized, reject opcode 0x%x",
++ opcode);
++ return -EOPNOTSUPP;
++ }
++
++ return 0;
++}
++
+ /**
+ * __bnxt_qplib_rcfw_send_message - qplib interface to send
+ * and complete rcfw command.
+@@ -299,29 +310,21 @@ static int __bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
+ {
+ struct creq_qp_event *evnt = (struct creq_qp_event *)msg->resp;
+ u16 cookie;
+- u8 opcode, retry_cnt = 0xFF;
+ int rc = 0;
++ u8 opcode;
+
+- /* Prevent posting if f/w is not in a state to process */
+- if (test_bit(ERR_DEVICE_DETACHED, &rcfw->cmdq.flags))
+- return 0;
++ opcode = __get_cmdq_base_opcode(msg->req, msg->req_sz);
+
+- do {
+- opcode = __get_cmdq_base_opcode(msg->req, msg->req_sz);
+- rc = __send_message(rcfw, msg);
+- cookie = le16_to_cpu(__get_cmdq_base_cookie(msg->req, msg->req_sz)) &
+- RCFW_MAX_COOKIE_VALUE;
+- if (!rc)
+- break;
+- if (!retry_cnt || (rc != -EAGAIN && rc != -EBUSY)) {
+- /* send failed */
+- dev_err(&rcfw->pdev->dev, "cmdq[%#x]=%#x send failed\n",
+- cookie, opcode);
+- return rc;
+- }
+- msg->block ? mdelay(1) : usleep_range(500, 1000);
++ rc = __send_message_basic_sanity(rcfw, msg);
++ if (rc)
++ return rc == -ENXIO ? bnxt_qplib_map_rc(opcode) : rc;
++
++ rc = __send_message(rcfw, msg);
++ if (rc)
++ return rc;
+
+- } while (retry_cnt--);
++ cookie = le16_to_cpu(__get_cmdq_base_cookie(msg->req, msg->req_sz))
++ & RCFW_MAX_COOKIE_VALUE;
+
+ if (msg->block)
+ rc = __block_for_resp(rcfw, cookie, opcode);
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
+index 675c388348827..43dc11febf46a 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
+@@ -91,6 +91,26 @@ static inline u32 bnxt_qplib_cmdqe_page_size(u32 depth)
+ return (bnxt_qplib_cmdqe_npages(depth) * PAGE_SIZE);
+ }
+
++/* Get the number of command units required for the req. The
++ * function returns correct value only if called before
++ * setting using bnxt_qplib_set_cmd_slots
++ */
++static inline u32 bnxt_qplib_get_cmd_slots(struct cmdq_base *req)
++{
++ u32 cmd_units = 0;
++
++ if (HAS_TLV_HEADER(req)) {
++ struct roce_tlv *tlv_req = (struct roce_tlv *)req;
++
++ cmd_units = tlv_req->total_size;
++ } else {
++ cmd_units = (req->cmd_size + BNXT_QPLIB_CMDQE_UNITS - 1) /
++ BNXT_QPLIB_CMDQE_UNITS;
++ }
++
++ return cmd_units;
++}
++
+ static inline u32 bnxt_qplib_set_cmd_slots(struct cmdq_base *req)
+ {
+ u32 cmd_byte = 0;
+@@ -134,6 +154,8 @@ typedef int (*aeq_handler_t)(struct bnxt_qplib_rcfw *, void *, void *);
+ struct bnxt_qplib_crsqe {
+ struct creq_qp_event *resp;
+ u32 req_size;
++ /* Free slots at the time of submission */
++ u32 free_slots;
+ };
+
+ struct bnxt_qplib_rcfw_sbuf {
+--
+2.40.1
+
--- /dev/null
+From 784300fccdc271d59d752d35b593b2fdf52bc40d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jun 2023 04:01:44 -0700
+Subject: RDMA/bnxt_re: use shadow qd while posting non blocking rcfw command
+
+From: Kashyap Desai <kashyap.desai@broadcom.com>
+
+[ Upstream commit 65288a22ddd81422a2a2a10c15df976a5332e41b ]
+
+Whenever there is a fast path IO and create/destroy resources from
+the slow path is happening in parallel, we may notice high latency
+of slow path command completion.
+
+Introduces a shadow queue depth to prevent the outstanding requests
+to the FW. Driver will not allow more than #RCFW_CMD_NON_BLOCKING_SHADOW_QD
+non-blocking commands to the Firmware.
+
+Shadow queue depth is a soft limit only for non-blocking
+commands. Blocking commands will be posted to the firmware
+as long as there is a free slot.
+
+Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Link: https://lore.kernel.org/r/1686308514-11996-8-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: 29900bf351e1 ("RDMA/bnxt_re: Fix hang during driver unload")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 60 +++++++++++++++++++++-
+ drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 3 ++
+ 2 files changed, 61 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+index bfa0f29c7abf4..42484a1149c7c 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+@@ -281,8 +281,21 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw,
+ return 0;
+ }
+
+-int bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
+- struct bnxt_qplib_cmdqmsg *msg)
++/**
++ * __bnxt_qplib_rcfw_send_message - qplib interface to send
++ * and complete rcfw command.
++ * @rcfw - rcfw channel instance of rdev
++ * @msg - qplib message internal
++ *
++ * This function does not account shadow queue depth. It will send
++ * all the command unconditionally as long as send queue is not full.
++ *
++ * Returns:
++ * 0 if command completed by firmware.
++ * Non zero if the command is not completed by firmware.
++ */
++static int __bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
++ struct bnxt_qplib_cmdqmsg *msg)
+ {
+ struct creq_qp_event *evnt = (struct creq_qp_event *)msg->resp;
+ u16 cookie;
+@@ -331,6 +344,48 @@ int bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
+
+ return rc;
+ }
++
++/**
++ * bnxt_qplib_rcfw_send_message - qplib interface to send
++ * and complete rcfw command.
++ * @rcfw - rcfw channel instance of rdev
++ * @msg - qplib message internal
++ *
++ * Driver interact with Firmware through rcfw channel/slow path in two ways.
++ * a. Blocking rcfw command send. In this path, driver cannot hold
++ * the context for longer period since it is holding cpu until
++ * command is not completed.
++ * b. Non-blocking rcfw command send. In this path, driver can hold the
++ * context for longer period. There may be many pending command waiting
++ * for completion because of non-blocking nature.
++ *
++ * Driver will use shadow queue depth. Current queue depth of 8K
++ * (due to size of rcfw message there can be actual ~4K rcfw outstanding)
++ * is not optimal for rcfw command processing in firmware.
++ *
++ * Restrict at max #RCFW_CMD_NON_BLOCKING_SHADOW_QD Non-Blocking rcfw commands.
++ * Allow all blocking commands until there is no queue full.
++ *
++ * Returns:
++ * 0 if command completed by firmware.
++ * Non zero if the command is not completed by firmware.
++ */
++int bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
++ struct bnxt_qplib_cmdqmsg *msg)
++{
++ int ret;
++
++ if (!msg->block) {
++ down(&rcfw->rcfw_inflight);
++ ret = __bnxt_qplib_rcfw_send_message(rcfw, msg);
++ up(&rcfw->rcfw_inflight);
++ } else {
++ ret = __bnxt_qplib_rcfw_send_message(rcfw, msg);
++ }
++
++ return ret;
++}
++
+ /* Completions */
+ static int bnxt_qplib_process_func_event(struct bnxt_qplib_rcfw *rcfw,
+ struct creq_func_event *func_event)
+@@ -937,6 +992,7 @@ int bnxt_qplib_enable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw,
+ return rc;
+ }
+
++ sema_init(&rcfw->rcfw_inflight, RCFW_CMD_NON_BLOCKING_SHADOW_QD);
+ bnxt_qplib_start_rcfw(rcfw);
+
+ return 0;
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
+index 92f7a25533d3b..675c388348827 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
+@@ -67,6 +67,8 @@ static inline void bnxt_qplib_rcfw_cmd_prep(struct cmdq_base *req,
+ req->cmd_size = cmd_size;
+ }
+
++/* Shadow queue depth for non blocking command */
++#define RCFW_CMD_NON_BLOCKING_SHADOW_QD 64
+ #define RCFW_CMD_WAIT_TIME_MS 20000 /* 20 Seconds timeout */
+
+ /* CMDQ elements */
+@@ -201,6 +203,7 @@ struct bnxt_qplib_rcfw {
+ u64 oos_prev;
+ u32 init_oos_stats;
+ u32 cmdq_depth;
++ struct semaphore rcfw_inflight;
+ };
+
+ struct bnxt_qplib_cmdqmsg {
+--
+2.40.1
+
--- /dev/null
+From 4474e23a7d494cb856f39dbd0916ddf5c2e0fe3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jul 2023 18:41:33 -0500
+Subject: RDMA/core: Update CMA destination address on rdma_resolve_addr
+
+From: Shiraz Saleem <shiraz.saleem@intel.com>
+
+[ Upstream commit 0e15863015d97c1ee2cc29d599abcc7fa2dc3e95 ]
+
+8d037973d48c ("RDMA/core: Refactor rdma_bind_addr") intoduces as regression
+on irdma devices on certain tests which uses rdma CM, such as cmtime.
+
+No connections can be established with the MAD QP experiences a fatal
+error on the active side.
+
+The cma destination address is not updated with the dst_addr when ULP
+on active side calls rdma_bind_addr followed by rdma_resolve_addr.
+The id_priv state is 'bound' in resolve_prepare_src and update is skipped.
+
+This leaves the dgid passed into irdma driver to create an Address Handle
+(AH) for the MAD QP at 0. The create AH descriptor as well as the ARP cache
+entry is invalid and HW throws an asynchronous events as result.
+
+[ 1207.656888] resolve_prepare_src caller: ucma_resolve_addr+0xff/0x170 [rdma_ucm] daddr=200.0.4.28 id_priv->state=7
+[....]
+[ 1207.680362] ice 0000:07:00.1 rocep7s0f1: caller: irdma_create_ah+0x3e/0x70 [irdma] ah_id=0 arp_idx=0 dest_ip=0.0.0.0
+destMAC=00:00:64:ca:b7:52 ipvalid=1 raw=0000:0000:0000:0000:0000:ffff:0000:0000
+[ 1207.682077] ice 0000:07:00.1 rocep7s0f1: abnormal ae_id = 0x401 bool qp=1 qp_id = 1, ae_src=5
+[ 1207.691657] infiniband rocep7s0f1: Fatal error (1) on MAD QP (1)
+
+Fix this by updating the CMA destination address when the ULP calls
+a resolve address with the CM state already bound.
+
+Fixes: 8d037973d48c ("RDMA/core: Refactor rdma_bind_addr")
+Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Link: https://lore.kernel.org/r/20230712234133.1343-1-shiraz.saleem@intel.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cma.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
+index 6b3f4384e46ac..a60e587aea817 100644
+--- a/drivers/infiniband/core/cma.c
++++ b/drivers/infiniband/core/cma.c
+@@ -4062,6 +4062,8 @@ static int resolve_prepare_src(struct rdma_id_private *id_priv,
+ RDMA_CM_ADDR_QUERY)))
+ return -EINVAL;
+
++ } else {
++ memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr));
+ }
+
+ if (cma_family(id_priv) != dst_addr->sa_family) {
+--
+2.40.1
+
--- /dev/null
+From 56816c5fadd526ee889a94b77896a7608ef077a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Jul 2023 12:52:51 -0500
+Subject: RDMA/irdma: Add missing read barriers
+
+From: Shiraz Saleem <shiraz.saleem@intel.com>
+
+[ Upstream commit 4984eb51453ff7eddee9e5ce816145be39c0ec5c ]
+
+On code inspection, there are many instances in the driver where
+CEQE and AEQE fields written to by HW are read without guaranteeing
+that the polarity bit has been read and checked first.
+
+Add a read barrier to avoid reordering of loads on the CEQE/AEQE fields
+prior to checking the polarity bit.
+
+Fixes: 3f49d6842569 ("RDMA/irdma: Implement HW Admin Queue OPs")
+Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Link: https://lore.kernel.org/r/20230711175253.1289-2-shiraz.saleem@intel.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/ctrl.c | 9 ++++++++-
+ drivers/infiniband/hw/irdma/puda.c | 6 ++++++
+ drivers/infiniband/hw/irdma/uk.c | 3 +++
+ 3 files changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/irdma/ctrl.c b/drivers/infiniband/hw/irdma/ctrl.c
+index d88c9184007ea..c91439f428c76 100644
+--- a/drivers/infiniband/hw/irdma/ctrl.c
++++ b/drivers/infiniband/hw/irdma/ctrl.c
+@@ -3363,6 +3363,9 @@ int irdma_sc_ccq_get_cqe_info(struct irdma_sc_cq *ccq,
+ if (polarity != ccq->cq_uk.polarity)
+ return -ENOENT;
+
++ /* Ensure CEQE contents are read after valid bit is checked */
++ dma_rmb();
++
+ get_64bit_val(cqe, 8, &qp_ctx);
+ cqp = (struct irdma_sc_cqp *)(unsigned long)qp_ctx;
+ info->error = (bool)FIELD_GET(IRDMA_CQ_ERROR, temp);
+@@ -4009,13 +4012,17 @@ int irdma_sc_get_next_aeqe(struct irdma_sc_aeq *aeq,
+ u8 polarity;
+
+ aeqe = IRDMA_GET_CURRENT_AEQ_ELEM(aeq);
+- get_64bit_val(aeqe, 0, &compl_ctx);
+ get_64bit_val(aeqe, 8, &temp);
+ polarity = (u8)FIELD_GET(IRDMA_AEQE_VALID, temp);
+
+ if (aeq->polarity != polarity)
+ return -ENOENT;
+
++ /* Ensure AEQE contents are read after valid bit is checked */
++ dma_rmb();
++
++ get_64bit_val(aeqe, 0, &compl_ctx);
++
+ print_hex_dump_debug("WQE: AEQ_ENTRY WQE", DUMP_PREFIX_OFFSET, 16, 8,
+ aeqe, 16, false);
+
+diff --git a/drivers/infiniband/hw/irdma/puda.c b/drivers/infiniband/hw/irdma/puda.c
+index 4ec9639f1bdbf..562531712ea44 100644
+--- a/drivers/infiniband/hw/irdma/puda.c
++++ b/drivers/infiniband/hw/irdma/puda.c
+@@ -230,6 +230,9 @@ static int irdma_puda_poll_info(struct irdma_sc_cq *cq,
+ if (valid_bit != cq_uk->polarity)
+ return -ENOENT;
+
++ /* Ensure CQE contents are read after valid bit is checked */
++ dma_rmb();
++
+ if (cq->dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2)
+ ext_valid = (bool)FIELD_GET(IRDMA_CQ_EXTCQE, qword3);
+
+@@ -243,6 +246,9 @@ static int irdma_puda_poll_info(struct irdma_sc_cq *cq,
+ if (polarity != cq_uk->polarity)
+ return -ENOENT;
+
++ /* Ensure ext CQE contents are read after ext valid bit is checked */
++ dma_rmb();
++
+ IRDMA_RING_MOVE_HEAD_NOCHECK(cq_uk->cq_ring);
+ if (!IRDMA_RING_CURRENT_HEAD(cq_uk->cq_ring))
+ cq_uk->polarity = !cq_uk->polarity;
+diff --git a/drivers/infiniband/hw/irdma/uk.c b/drivers/infiniband/hw/irdma/uk.c
+index dd428d915c175..ea2c07751245a 100644
+--- a/drivers/infiniband/hw/irdma/uk.c
++++ b/drivers/infiniband/hw/irdma/uk.c
+@@ -1527,6 +1527,9 @@ void irdma_uk_clean_cq(void *q, struct irdma_cq_uk *cq)
+ if (polarity != temp)
+ break;
+
++ /* Ensure CQE contents are read after valid bit is checked */
++ dma_rmb();
++
+ get_64bit_val(cqe, 8, &comp_ctx);
+ if ((void *)(unsigned long)comp_ctx == q)
+ set_64bit_val(cqe, 8, 0);
+--
+2.40.1
+
--- /dev/null
+From d3bad7987f1d6e80e720b7e5b7b38fa9ed1f349c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Jul 2023 12:52:52 -0500
+Subject: RDMA/irdma: Fix data race on CQP completion stats
+
+From: Shiraz Saleem <shiraz.saleem@intel.com>
+
+[ Upstream commit f2c3037811381f9149243828c7eb9a1631df9f9c ]
+
+CQP completion statistics is read lockesly in irdma_wait_event and
+irdma_check_cqp_progress while it can be updated in the completion
+thread irdma_sc_ccq_get_cqe_info on another CPU as KCSAN reports.
+
+Make completion statistics an atomic variable to reflect coherent updates
+to it. This will also avoid load/store tearing logic bug potentially
+possible by compiler optimizations.
+
+[77346.170861] BUG: KCSAN: data-race in irdma_handle_cqp_op [irdma] / irdma_sc_ccq_get_cqe_info [irdma]
+
+[77346.171383] write to 0xffff8a3250b108e0 of 8 bytes by task 9544 on cpu 4:
+[77346.171483] irdma_sc_ccq_get_cqe_info+0x27a/0x370 [irdma]
+[77346.171658] irdma_cqp_ce_handler+0x164/0x270 [irdma]
+[77346.171835] cqp_compl_worker+0x1b/0x20 [irdma]
+[77346.172009] process_one_work+0x4d1/0xa40
+[77346.172024] worker_thread+0x319/0x700
+[77346.172037] kthread+0x180/0x1b0
+[77346.172054] ret_from_fork+0x22/0x30
+
+[77346.172136] read to 0xffff8a3250b108e0 of 8 bytes by task 9838 on cpu 2:
+[77346.172234] irdma_handle_cqp_op+0xf4/0x4b0 [irdma]
+[77346.172413] irdma_cqp_aeq_cmd+0x75/0xa0 [irdma]
+[77346.172592] irdma_create_aeq+0x390/0x45a [irdma]
+[77346.172769] irdma_rt_init_hw.cold+0x212/0x85d [irdma]
+[77346.172944] irdma_probe+0x54f/0x620 [irdma]
+[77346.173122] auxiliary_bus_probe+0x66/0xa0
+[77346.173137] really_probe+0x140/0x540
+[77346.173154] __driver_probe_device+0xc7/0x220
+[77346.173173] driver_probe_device+0x5f/0x140
+[77346.173190] __driver_attach+0xf0/0x2c0
+[77346.173208] bus_for_each_dev+0xa8/0xf0
+[77346.173225] driver_attach+0x29/0x30
+[77346.173240] bus_add_driver+0x29c/0x2f0
+[77346.173255] driver_register+0x10f/0x1a0
+[77346.173272] __auxiliary_driver_register+0xbc/0x140
+[77346.173287] irdma_init_module+0x55/0x1000 [irdma]
+[77346.173460] do_one_initcall+0x7d/0x410
+[77346.173475] do_init_module+0x81/0x2c0
+[77346.173491] load_module+0x1232/0x12c0
+[77346.173506] __do_sys_finit_module+0x101/0x180
+[77346.173522] __x64_sys_finit_module+0x3c/0x50
+[77346.173538] do_syscall_64+0x39/0x90
+[77346.173553] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+[77346.173634] value changed: 0x0000000000000094 -> 0x0000000000000095
+
+Fixes: 915cc7ac0f8e ("RDMA/irdma: Add miscellaneous utility definitions")
+Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Link: https://lore.kernel.org/r/20230711175253.1289-3-shiraz.saleem@intel.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/ctrl.c | 22 +++++++-------
+ drivers/infiniband/hw/irdma/defs.h | 46 ++++++++++++++---------------
+ drivers/infiniband/hw/irdma/type.h | 2 ++
+ drivers/infiniband/hw/irdma/utils.c | 2 +-
+ 4 files changed, 36 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/ctrl.c b/drivers/infiniband/hw/irdma/ctrl.c
+index c91439f428c76..45e3344daa048 100644
+--- a/drivers/infiniband/hw/irdma/ctrl.c
++++ b/drivers/infiniband/hw/irdma/ctrl.c
+@@ -2712,13 +2712,13 @@ static int irdma_sc_cq_modify(struct irdma_sc_cq *cq,
+ */
+ void irdma_check_cqp_progress(struct irdma_cqp_timeout *timeout, struct irdma_sc_dev *dev)
+ {
+- if (timeout->compl_cqp_cmds != dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]) {
+- timeout->compl_cqp_cmds = dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS];
++ u64 completed_ops = atomic64_read(&dev->cqp->completed_ops);
++
++ if (timeout->compl_cqp_cmds != completed_ops) {
++ timeout->compl_cqp_cmds = completed_ops;
+ timeout->count = 0;
+- } else {
+- if (dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS] !=
+- timeout->compl_cqp_cmds)
+- timeout->count++;
++ } else if (timeout->compl_cqp_cmds != dev->cqp->requested_ops) {
++ timeout->count++;
+ }
+ }
+
+@@ -2761,7 +2761,7 @@ static int irdma_cqp_poll_registers(struct irdma_sc_cqp *cqp, u32 tail,
+ if (newtail != tail) {
+ /* SUCCESS */
+ IRDMA_RING_MOVE_TAIL(cqp->sq_ring);
+- cqp->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]++;
++ atomic64_inc(&cqp->completed_ops);
+ return 0;
+ }
+ udelay(cqp->dev->hw_attrs.max_sleep_count);
+@@ -3121,8 +3121,8 @@ int irdma_sc_cqp_init(struct irdma_sc_cqp *cqp,
+ info->dev->cqp = cqp;
+
+ IRDMA_RING_INIT(cqp->sq_ring, cqp->sq_size);
+- cqp->dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS] = 0;
+- cqp->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS] = 0;
++ cqp->requested_ops = 0;
++ atomic64_set(&cqp->completed_ops, 0);
+ /* for the cqp commands backlog. */
+ INIT_LIST_HEAD(&cqp->dev->cqp_cmd_head);
+
+@@ -3274,7 +3274,7 @@ __le64 *irdma_sc_cqp_get_next_send_wqe_idx(struct irdma_sc_cqp *cqp, u64 scratch
+ if (ret_code)
+ return NULL;
+
+- cqp->dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS]++;
++ cqp->requested_ops++;
+ if (!*wqe_idx)
+ cqp->polarity = !cqp->polarity;
+ wqe = cqp->sq_base[*wqe_idx].elem;
+@@ -3400,7 +3400,7 @@ int irdma_sc_ccq_get_cqe_info(struct irdma_sc_cq *ccq,
+ dma_wmb(); /* make sure shadow area is updated before moving tail */
+
+ IRDMA_RING_MOVE_TAIL(cqp->sq_ring);
+- ccq->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]++;
++ atomic64_inc(&cqp->completed_ops);
+
+ return ret_code;
+ }
+diff --git a/drivers/infiniband/hw/irdma/defs.h b/drivers/infiniband/hw/irdma/defs.h
+index 6014b9d06a9ba..d06e45d2c23fd 100644
+--- a/drivers/infiniband/hw/irdma/defs.h
++++ b/drivers/infiniband/hw/irdma/defs.h
+@@ -191,32 +191,30 @@ enum irdma_cqp_op_type {
+ IRDMA_OP_MANAGE_VF_PBLE_BP = 25,
+ IRDMA_OP_QUERY_FPM_VAL = 26,
+ IRDMA_OP_COMMIT_FPM_VAL = 27,
+- IRDMA_OP_REQ_CMDS = 28,
+- IRDMA_OP_CMPL_CMDS = 29,
+- IRDMA_OP_AH_CREATE = 30,
+- IRDMA_OP_AH_MODIFY = 31,
+- IRDMA_OP_AH_DESTROY = 32,
+- IRDMA_OP_MC_CREATE = 33,
+- IRDMA_OP_MC_DESTROY = 34,
+- IRDMA_OP_MC_MODIFY = 35,
+- IRDMA_OP_STATS_ALLOCATE = 36,
+- IRDMA_OP_STATS_FREE = 37,
+- IRDMA_OP_STATS_GATHER = 38,
+- IRDMA_OP_WS_ADD_NODE = 39,
+- IRDMA_OP_WS_MODIFY_NODE = 40,
+- IRDMA_OP_WS_DELETE_NODE = 41,
+- IRDMA_OP_WS_FAILOVER_START = 42,
+- IRDMA_OP_WS_FAILOVER_COMPLETE = 43,
+- IRDMA_OP_SET_UP_MAP = 44,
+- IRDMA_OP_GEN_AE = 45,
+- IRDMA_OP_QUERY_RDMA_FEATURES = 46,
+- IRDMA_OP_ALLOC_LOCAL_MAC_ENTRY = 47,
+- IRDMA_OP_ADD_LOCAL_MAC_ENTRY = 48,
+- IRDMA_OP_DELETE_LOCAL_MAC_ENTRY = 49,
+- IRDMA_OP_CQ_MODIFY = 50,
++ IRDMA_OP_AH_CREATE = 28,
++ IRDMA_OP_AH_MODIFY = 29,
++ IRDMA_OP_AH_DESTROY = 30,
++ IRDMA_OP_MC_CREATE = 31,
++ IRDMA_OP_MC_DESTROY = 32,
++ IRDMA_OP_MC_MODIFY = 33,
++ IRDMA_OP_STATS_ALLOCATE = 34,
++ IRDMA_OP_STATS_FREE = 35,
++ IRDMA_OP_STATS_GATHER = 36,
++ IRDMA_OP_WS_ADD_NODE = 37,
++ IRDMA_OP_WS_MODIFY_NODE = 38,
++ IRDMA_OP_WS_DELETE_NODE = 39,
++ IRDMA_OP_WS_FAILOVER_START = 40,
++ IRDMA_OP_WS_FAILOVER_COMPLETE = 41,
++ IRDMA_OP_SET_UP_MAP = 42,
++ IRDMA_OP_GEN_AE = 43,
++ IRDMA_OP_QUERY_RDMA_FEATURES = 44,
++ IRDMA_OP_ALLOC_LOCAL_MAC_ENTRY = 45,
++ IRDMA_OP_ADD_LOCAL_MAC_ENTRY = 46,
++ IRDMA_OP_DELETE_LOCAL_MAC_ENTRY = 47,
++ IRDMA_OP_CQ_MODIFY = 48,
+
+ /* Must be last entry*/
+- IRDMA_MAX_CQP_OPS = 51,
++ IRDMA_MAX_CQP_OPS = 49,
+ };
+
+ /* CQP SQ WQES */
+diff --git a/drivers/infiniband/hw/irdma/type.h b/drivers/infiniband/hw/irdma/type.h
+index 5ee68604e59fc..a20709577ab0a 100644
+--- a/drivers/infiniband/hw/irdma/type.h
++++ b/drivers/infiniband/hw/irdma/type.h
+@@ -365,6 +365,8 @@ struct irdma_sc_cqp {
+ struct irdma_dcqcn_cc_params dcqcn_params;
+ __le64 *host_ctx;
+ u64 *scratch_array;
++ u64 requested_ops;
++ atomic64_t completed_ops;
+ u32 cqp_id;
+ u32 sq_size;
+ u32 hw_sq_size;
+diff --git a/drivers/infiniband/hw/irdma/utils.c b/drivers/infiniband/hw/irdma/utils.c
+index 71e1c5d347092..775a79946f7df 100644
+--- a/drivers/infiniband/hw/irdma/utils.c
++++ b/drivers/infiniband/hw/irdma/utils.c
+@@ -567,7 +567,7 @@ static int irdma_wait_event(struct irdma_pci_f *rf,
+ bool cqp_error = false;
+ int err_code = 0;
+
+- cqp_timeout.compl_cqp_cmds = rf->sc_dev.cqp_cmd_stats[IRDMA_OP_CMPL_CMDS];
++ cqp_timeout.compl_cqp_cmds = atomic64_read(&rf->sc_dev.cqp->completed_ops);
+ do {
+ irdma_cqp_ce_handler(rf, &rf->ccq.sc_cq);
+ if (wait_event_timeout(cqp_request->waitq,
+--
+2.40.1
+
--- /dev/null
+From 1c543ca10f836e7e0808052d8b6126258d49bd0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Jul 2023 12:52:53 -0500
+Subject: RDMA/irdma: Fix data race on CQP request done
+
+From: Shiraz Saleem <shiraz.saleem@intel.com>
+
+[ Upstream commit f0842bb3d38863777e3454da5653d80b5fde6321 ]
+
+KCSAN detects a data race on cqp_request->request_done memory location
+which is accessed locklessly in irdma_handle_cqp_op while being
+updated in irdma_cqp_ce_handler.
+
+Annotate lockless intent with READ_ONCE/WRITE_ONCE to avoid any
+compiler optimizations like load fusing and/or KCSAN warning.
+
+[222808.417128] BUG: KCSAN: data-race in irdma_cqp_ce_handler [irdma] / irdma_wait_event [irdma]
+
+[222808.417532] write to 0xffff8e44107019dc of 1 bytes by task 29658 on cpu 5:
+[222808.417610] irdma_cqp_ce_handler+0x21e/0x270 [irdma]
+[222808.417725] cqp_compl_worker+0x1b/0x20 [irdma]
+[222808.417827] process_one_work+0x4d1/0xa40
+[222808.417835] worker_thread+0x319/0x700
+[222808.417842] kthread+0x180/0x1b0
+[222808.417852] ret_from_fork+0x22/0x30
+
+[222808.417918] read to 0xffff8e44107019dc of 1 bytes by task 29688 on cpu 1:
+[222808.417995] irdma_wait_event+0x1e2/0x2c0 [irdma]
+[222808.418099] irdma_handle_cqp_op+0xae/0x170 [irdma]
+[222808.418202] irdma_cqp_cq_destroy_cmd+0x70/0x90 [irdma]
+[222808.418308] irdma_puda_dele_rsrc+0x46d/0x4d0 [irdma]
+[222808.418411] irdma_rt_deinit_hw+0x179/0x1d0 [irdma]
+[222808.418514] irdma_ib_dealloc_device+0x11/0x40 [irdma]
+[222808.418618] ib_dealloc_device+0x2a/0x120 [ib_core]
+[222808.418823] __ib_unregister_device+0xde/0x100 [ib_core]
+[222808.418981] ib_unregister_device+0x22/0x40 [ib_core]
+[222808.419142] irdma_ib_unregister_device+0x70/0x90 [irdma]
+[222808.419248] i40iw_close+0x6f/0xc0 [irdma]
+[222808.419352] i40e_client_device_unregister+0x14a/0x180 [i40e]
+[222808.419450] i40iw_remove+0x21/0x30 [irdma]
+[222808.419554] auxiliary_bus_remove+0x31/0x50
+[222808.419563] device_remove+0x69/0xb0
+[222808.419572] device_release_driver_internal+0x293/0x360
+[222808.419582] driver_detach+0x7c/0xf0
+[222808.419592] bus_remove_driver+0x8c/0x150
+[222808.419600] driver_unregister+0x45/0x70
+[222808.419610] auxiliary_driver_unregister+0x16/0x30
+[222808.419618] irdma_exit_module+0x18/0x1e [irdma]
+[222808.419733] __do_sys_delete_module.constprop.0+0x1e2/0x310
+[222808.419745] __x64_sys_delete_module+0x1b/0x30
+[222808.419755] do_syscall_64+0x39/0x90
+[222808.419763] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+[222808.419829] value changed: 0x01 -> 0x03
+
+Fixes: 915cc7ac0f8e ("RDMA/irdma: Add miscellaneous utility definitions")
+Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Link: https://lore.kernel.org/r/20230711175253.1289-4-shiraz.saleem@intel.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/hw.c | 2 +-
+ drivers/infiniband/hw/irdma/main.h | 2 +-
+ drivers/infiniband/hw/irdma/utils.c | 6 +++---
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c
+index 795f7fd4f2574..1cfc03da89e7a 100644
+--- a/drivers/infiniband/hw/irdma/hw.c
++++ b/drivers/infiniband/hw/irdma/hw.c
+@@ -2075,7 +2075,7 @@ void irdma_cqp_ce_handler(struct irdma_pci_f *rf, struct irdma_sc_cq *cq)
+ cqp_request->compl_info.error = info.error;
+
+ if (cqp_request->waiting) {
+- cqp_request->request_done = true;
++ WRITE_ONCE(cqp_request->request_done, true);
+ wake_up(&cqp_request->waitq);
+ irdma_put_cqp_request(&rf->cqp, cqp_request);
+ } else {
+diff --git a/drivers/infiniband/hw/irdma/main.h b/drivers/infiniband/hw/irdma/main.h
+index def6dd58dcd48..2323962cdeacb 100644
+--- a/drivers/infiniband/hw/irdma/main.h
++++ b/drivers/infiniband/hw/irdma/main.h
+@@ -161,8 +161,8 @@ struct irdma_cqp_request {
+ void (*callback_fcn)(struct irdma_cqp_request *cqp_request);
+ void *param;
+ struct irdma_cqp_compl_info compl_info;
++ bool request_done; /* READ/WRITE_ONCE macros operate on it */
+ bool waiting:1;
+- bool request_done:1;
+ bool dynamic:1;
+ };
+
+diff --git a/drivers/infiniband/hw/irdma/utils.c b/drivers/infiniband/hw/irdma/utils.c
+index 775a79946f7df..eb083f70b09ff 100644
+--- a/drivers/infiniband/hw/irdma/utils.c
++++ b/drivers/infiniband/hw/irdma/utils.c
+@@ -481,7 +481,7 @@ void irdma_free_cqp_request(struct irdma_cqp *cqp,
+ if (cqp_request->dynamic) {
+ kfree(cqp_request);
+ } else {
+- cqp_request->request_done = false;
++ WRITE_ONCE(cqp_request->request_done, false);
+ cqp_request->callback_fcn = NULL;
+ cqp_request->waiting = false;
+
+@@ -515,7 +515,7 @@ irdma_free_pending_cqp_request(struct irdma_cqp *cqp,
+ {
+ if (cqp_request->waiting) {
+ cqp_request->compl_info.error = true;
+- cqp_request->request_done = true;
++ WRITE_ONCE(cqp_request->request_done, true);
+ wake_up(&cqp_request->waitq);
+ }
+ wait_event_timeout(cqp->remove_wq,
+@@ -571,7 +571,7 @@ static int irdma_wait_event(struct irdma_pci_f *rf,
+ do {
+ irdma_cqp_ce_handler(rf, &rf->ccq.sc_cq);
+ if (wait_event_timeout(cqp_request->waitq,
+- cqp_request->request_done,
++ READ_ONCE(cqp_request->request_done),
+ msecs_to_jiffies(CQP_COMPL_WAIT_TIME_MS)))
+ break;
+
+--
+2.40.1
+
--- /dev/null
+From 3439c5099007eb8e418f36a85092f6d339d6e565 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 10:54:37 -0500
+Subject: RDMA/irdma: Fix op_type reporting in CQEs
+
+From: Sindhu Devale <sindhu.devale@intel.com>
+
+[ Upstream commit 3bfb25fa2b5bb9c29681e6ac861808f4be1331a9 ]
+
+The op_type field CQ poll info structure is incorrectly
+filled in with the queue type as opposed to the op_type
+received in the CQEs. The wrong opcode could be decoded
+and returned to the ULP.
+
+Copy the op_type field received in the CQE in the CQ poll
+info structure.
+
+Fixes: 24419777e943 ("RDMA/irdma: Fix RQ completion opcode")
+Signed-off-by: Sindhu Devale <sindhu.devale@intel.com>
+Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Link: https://lore.kernel.org/r/20230725155439.1057-1-shiraz.saleem@intel.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/uk.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/irdma/uk.c b/drivers/infiniband/hw/irdma/uk.c
+index ea2c07751245a..280d633d4ec4f 100644
+--- a/drivers/infiniband/hw/irdma/uk.c
++++ b/drivers/infiniband/hw/irdma/uk.c
+@@ -1161,7 +1161,7 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq,
+ }
+ wqe_idx = (u32)FIELD_GET(IRDMA_CQ_WQEIDX, qword3);
+ info->qp_handle = (irdma_qp_handle)(unsigned long)qp;
+- info->op_type = (u8)FIELD_GET(IRDMA_CQ_SQ, qword3);
++ info->op_type = (u8)FIELD_GET(IRDMACQ_OP, qword3);
+
+ if (info->q_type == IRDMA_CQE_QTYPE_RQ) {
+ u32 array_idx;
+--
+2.40.1
+
--- /dev/null
+From b293f8e1abe916f4b36ea3b9a097d564e9c36f37 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 10:54:38 -0500
+Subject: RDMA/irdma: Report correct WC error
+
+From: Sindhu Devale <sindhu.devale@intel.com>
+
+[ Upstream commit ae463563b7a1b7d4a3d0b065b09d37a76b693937 ]
+
+Report the correct WC error if a MW bind is performed
+on an already valid/bound window.
+
+Fixes: 44d9e52977a1 ("RDMA/irdma: Implement device initialization definitions")
+Signed-off-by: Sindhu Devale <sindhu.devale@intel.com>
+Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Link: https://lore.kernel.org/r/20230725155439.1057-2-shiraz.saleem@intel.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/hw.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c
+index 1cfc03da89e7a..457368e324e10 100644
+--- a/drivers/infiniband/hw/irdma/hw.c
++++ b/drivers/infiniband/hw/irdma/hw.c
+@@ -191,6 +191,7 @@ static void irdma_set_flush_fields(struct irdma_sc_qp *qp,
+ case IRDMA_AE_AMP_MWBIND_INVALID_RIGHTS:
+ case IRDMA_AE_AMP_MWBIND_BIND_DISABLED:
+ case IRDMA_AE_AMP_MWBIND_INVALID_BOUNDS:
++ case IRDMA_AE_AMP_MWBIND_VALID_STAG:
+ qp->flush_code = FLUSH_MW_BIND_ERR;
+ qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
+ break;
+--
+2.40.1
+
--- /dev/null
+From ace771a1761458b061d74569822dd88aa60e5d58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jun 2023 09:07:37 +0300
+Subject: RDMA/mlx4: Make check for invalid flags stricter
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit d64b1ee12a168030fbb3e0aebf7bce49e9a07589 ]
+
+This code is trying to ensure that only the flags specified in the list
+are allowed. The problem is that ucmd->rx_hash_fields_mask is a u64 and
+the flags are an enum which is treated as a u32 in this context. That
+means the test doesn't check whether the highest 32 bits are zero.
+
+Fixes: 4d02ebd9bbbd ("IB/mlx4: Fix RSS hash fields restrictions")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/r/233ed975-982d-422a-b498-410f71d8a101@moroto.mountain
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx4/qp.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
+index 456656617c33f..9d08aa99f3cb0 100644
+--- a/drivers/infiniband/hw/mlx4/qp.c
++++ b/drivers/infiniband/hw/mlx4/qp.c
+@@ -565,15 +565,15 @@ static int set_qp_rss(struct mlx4_ib_dev *dev, struct mlx4_ib_rss *rss_ctx,
+ return (-EOPNOTSUPP);
+ }
+
+- if (ucmd->rx_hash_fields_mask & ~(MLX4_IB_RX_HASH_SRC_IPV4 |
+- MLX4_IB_RX_HASH_DST_IPV4 |
+- MLX4_IB_RX_HASH_SRC_IPV6 |
+- MLX4_IB_RX_HASH_DST_IPV6 |
+- MLX4_IB_RX_HASH_SRC_PORT_TCP |
+- MLX4_IB_RX_HASH_DST_PORT_TCP |
+- MLX4_IB_RX_HASH_SRC_PORT_UDP |
+- MLX4_IB_RX_HASH_DST_PORT_UDP |
+- MLX4_IB_RX_HASH_INNER)) {
++ if (ucmd->rx_hash_fields_mask & ~(u64)(MLX4_IB_RX_HASH_SRC_IPV4 |
++ MLX4_IB_RX_HASH_DST_IPV4 |
++ MLX4_IB_RX_HASH_SRC_IPV6 |
++ MLX4_IB_RX_HASH_DST_IPV6 |
++ MLX4_IB_RX_HASH_SRC_PORT_TCP |
++ MLX4_IB_RX_HASH_DST_PORT_TCP |
++ MLX4_IB_RX_HASH_SRC_PORT_UDP |
++ MLX4_IB_RX_HASH_DST_PORT_UDP |
++ MLX4_IB_RX_HASH_INNER)) {
+ pr_debug("RX Hash fields_mask has unsupported mask (0x%llx)\n",
+ ucmd->rx_hash_fields_mask);
+ return (-EOPNOTSUPP);
+--
+2.40.1
+
--- /dev/null
+From 47e388bc7bbb63a331d8e285a643d6293ec631e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Jul 2023 16:16:58 +0200
+Subject: RDMA/mthca: Fix crash when polling CQ for shared QPs
+
+From: Thomas Bogendoerfer <tbogendoerfer@suse.de>
+
+[ Upstream commit dc52aadbc1849cbe3fcf6bc54d35f6baa396e0a1 ]
+
+Commit 21c2fe94abb2 ("RDMA/mthca: Combine special QP struct with mthca QP")
+introduced a new struct mthca_sqp which doesn't contain struct mthca_qp
+any longer. Placing a pointer of this new struct into qptable leads
+to crashes, because mthca_poll_one() expects a qp pointer. Fix this
+by putting the correct pointer into qptable.
+
+Fixes: 21c2fe94abb2 ("RDMA/mthca: Combine special QP struct with mthca QP")
+Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
+Link: https://lore.kernel.org/r/20230713141658.9426-1-tbogendoerfer@suse.de
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mthca/mthca_qp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
+index 69bba0ef4a5df..53f43649f7d08 100644
+--- a/drivers/infiniband/hw/mthca/mthca_qp.c
++++ b/drivers/infiniband/hw/mthca/mthca_qp.c
+@@ -1393,7 +1393,7 @@ int mthca_alloc_sqp(struct mthca_dev *dev,
+ if (mthca_array_get(&dev->qp_table.qp, mqpn))
+ err = -EBUSY;
+ else
+- mthca_array_set(&dev->qp_table.qp, mqpn, qp->sqp);
++ mthca_array_set(&dev->qp_table.qp, mqpn, qp);
+ spin_unlock_irq(&dev->qp_table.lock);
+
+ if (err)
+--
+2.40.1
+
--- /dev/null
+From 1e0119fd22f6f14c07c6607e1da88d733b946c81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jul 2023 13:40:40 +0800
+Subject: ring-buffer: Fix wrong stat of cpu_buffer->read
+
+From: Zheng Yejian <zhengyejian1@huawei.com>
+
+[ Upstream commit 2d093282b0d4357373497f65db6a05eb0c28b7c8 ]
+
+When pages are removed in rb_remove_pages(), 'cpu_buffer->read' is set
+to 0 in order to make sure any read iterators reset themselves. However,
+this will mess 'entries' stating, see following steps:
+
+ # cd /sys/kernel/tracing/
+ # 1. Enlarge ring buffer prepare for later reducing:
+ # echo 20 > per_cpu/cpu0/buffer_size_kb
+ # 2. Write a log into ring buffer of cpu0:
+ # taskset -c 0 echo "hello1" > trace_marker
+ # 3. Read the log:
+ # cat per_cpu/cpu0/trace_pipe
+ <...>-332 [000] ..... 62.406844: tracing_mark_write: hello1
+ # 4. Stop reading and see the stats, now 0 entries, and 1 event readed:
+ # cat per_cpu/cpu0/stats
+ entries: 0
+ [...]
+ read events: 1
+ # 5. Reduce the ring buffer
+ # echo 7 > per_cpu/cpu0/buffer_size_kb
+ # 6. Now entries became unexpected 1 because actually no entries!!!
+ # cat per_cpu/cpu0/stats
+ entries: 1
+ [...]
+ read events: 0
+
+To fix it, introduce 'page_removed' field to count total removed pages
+since last reset, then use it to let read iterators reset themselves
+instead of changing the 'read' pointer.
+
+Link: https://lore.kernel.org/linux-trace-kernel/20230724054040.3489499-1-zhengyejian1@huawei.com
+
+Cc: <mhiramat@kernel.org>
+Cc: <vnagarnaik@google.com>
+Fixes: 83f40318dab0 ("ring-buffer: Make removal of ring buffer pages atomic")
+Signed-off-by: Zheng Yejian <zhengyejian1@huawei.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/ring_buffer.c | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index 14d8001140c82..99634b29a8b82 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -523,6 +523,8 @@ struct ring_buffer_per_cpu {
+ rb_time_t before_stamp;
+ u64 event_stamp[MAX_NEST];
+ u64 read_stamp;
++ /* pages removed since last reset */
++ unsigned long pages_removed;
+ /* ring buffer pages to update, > 0 to add, < 0 to remove */
+ long nr_pages_to_update;
+ struct list_head new_pages; /* new pages to add */
+@@ -558,6 +560,7 @@ struct ring_buffer_iter {
+ struct buffer_page *head_page;
+ struct buffer_page *cache_reader_page;
+ unsigned long cache_read;
++ unsigned long cache_pages_removed;
+ u64 read_stamp;
+ u64 page_stamp;
+ struct ring_buffer_event *event;
+@@ -1956,6 +1959,8 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages)
+ to_remove = rb_list_head(to_remove)->next;
+ head_bit |= (unsigned long)to_remove & RB_PAGE_HEAD;
+ }
++ /* Read iterators need to reset themselves when some pages removed */
++ cpu_buffer->pages_removed += nr_removed;
+
+ next_page = rb_list_head(to_remove)->next;
+
+@@ -1977,12 +1982,6 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages)
+ cpu_buffer->head_page = list_entry(next_page,
+ struct buffer_page, list);
+
+- /*
+- * change read pointer to make sure any read iterators reset
+- * themselves
+- */
+- cpu_buffer->read = 0;
+-
+ /* pages are removed, resume tracing and then free the pages */
+ atomic_dec(&cpu_buffer->record_disabled);
+ raw_spin_unlock_irq(&cpu_buffer->reader_lock);
+@@ -4392,6 +4391,7 @@ static void rb_iter_reset(struct ring_buffer_iter *iter)
+
+ iter->cache_reader_page = iter->head_page;
+ iter->cache_read = cpu_buffer->read;
++ iter->cache_pages_removed = cpu_buffer->pages_removed;
+
+ if (iter->head) {
+ iter->read_stamp = cpu_buffer->read_stamp;
+@@ -4846,12 +4846,13 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
+ buffer = cpu_buffer->buffer;
+
+ /*
+- * Check if someone performed a consuming read to
+- * the buffer. A consuming read invalidates the iterator
+- * and we need to reset the iterator in this case.
++ * Check if someone performed a consuming read to the buffer
++ * or removed some pages from the buffer. In these cases,
++ * iterator was invalidated and we need to reset it.
+ */
+ if (unlikely(iter->cache_read != cpu_buffer->read ||
+- iter->cache_reader_page != cpu_buffer->reader_page))
++ iter->cache_reader_page != cpu_buffer->reader_page ||
++ iter->cache_pages_removed != cpu_buffer->pages_removed))
+ rb_iter_reset(iter);
+
+ again:
+@@ -5295,6 +5296,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
+ cpu_buffer->last_overrun = 0;
+
+ rb_head_page_activate(cpu_buffer);
++ cpu_buffer->pages_removed = 0;
+ }
+
+ /* Must have disabled the cpu buffer then done a synchronize_rcu */
+--
+2.40.1
+
benet-fix-return-value-check-in-be_lancer_xmit_worka.patch
tipc-check-return-value-of-pskb_trim.patch
tipc-stop-tipc-crypto-on-failure-in-tipc_node_create.patch
+fs-9p-fix-a-datatype-used-with-v9fs_direct_io.patch
+rdma-mlx4-make-check-for-invalid-flags-stricter.patch
+drm-msm-mdss-correct-ubwc-programming-for-sm8550.patch
+drm-msm-dpu-add-missing-flush-and-fetch-bits-for-dma.patch
+drm-msm-dpu-drop-enum-dpu_core_perf_data_bus_id.patch
+drm-msm-dsi-drop-unused-regulators-from-qcm2290-14nm.patch
+drm-msm-adreno-fix-snapshot-bindless_data-size.patch
+rdma-irdma-add-missing-read-barriers.patch
+rdma-irdma-fix-data-race-on-cqp-completion-stats.patch
+rdma-irdma-fix-data-race-on-cqp-request-done.patch
+rdma-core-update-cma-destination-address-on-rdma_res.patch
+rdma-mthca-fix-crash-when-polling-cq-for-shared-qps.patch
+rdma-bnxt_re-prevent-handling-any-completions-after-.patch
+rdma-bnxt_re-enhance-the-existing-functions-that-wai.patch
+rdma-bnxt_re-avoid-the-command-wait-if-firmware-is-i.patch
+rdma-bnxt_re-use-shadow-qd-while-posting-non-blockin.patch
+rdma-bnxt_re-simplify-the-function-that-sends-the-fw.patch
+rdma-bnxt_re-add-helper-function-__poll_for_resp.patch
+rdma-bnxt_re-fix-hang-during-driver-unload.patch
+drm-msm-fix-is_err_or_null-vs-null-check-in-a5xx_sub.patch
+drm-msm-fix-hw_fence-error-path-cleanup.patch
+cxl-acpi-fix-a-use-after-free-in-cxl_parse_cfmws.patch
+cxl-acpi-return-rc-instead-of-0-in-cxl_parse_cfmws.patch
+asoc-fsl_spdif-silence-output-on-stop.patch
+block-fix-a-source-code-comment-in-include-uapi-linu.patch
+smb3-do-not-set-ntlmssp_version-flag-for-negotiate-n.patch
+drm-i915-fix-an-error-handling-path-in-igt_write_hug.patch
+xenbus-check-xen_domain-in-xenbus_probe_initcall.patch
+dm-raid-fix-missing-reconfig_mutex-unlock-in-raid_ct.patch
+dm-raid-clean-up-four-equivalent-goto-tags-in-raid_c.patch
+dm-raid-protect-md_stop-with-reconfig_mutex.patch
+drm-amd-fix-an-error-handling-mistake-in-psp_sw_init.patch
+drm-amd-display-unlock-on-error-path-in-dm_handle_ms.patch
+rdma-irdma-fix-op_type-reporting-in-cqes.patch
+rdma-irdma-report-correct-wc-error.patch
+drm-msm-disallow-submit-with-fence-id-0.patch
+ublk-fail-to-start-device-if-queue-setup-is-interrup.patch
+ublk-fail-to-recover-device-if-queue-setup-is-interr.patch
+ublk-return-eintr-if-breaking-from-waiting-for-exist.patch
+iommufd-iommufd_destroy-should-not-increase-the-refc.patch
+tmpfs-fix-documentation-of-noswap-and-huge-mount-opt.patch
+ata-pata_ns87415-mark-ns87560_tf_read-static.patch
+ring-buffer-fix-wrong-stat-of-cpu_buffer-read.patch
+tracing-fix-warning-in-trace_buffered_event_disable.patch
--- /dev/null
+From b2e9b036a314c38c9a42c790ce0cd97b95bdbaff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 01:05:23 -0500
+Subject: smb3: do not set NTLMSSP_VERSION flag for negotiate not auth request
+
+From: Steve French <stfrench@microsoft.com>
+
+[ Upstream commit 19826558210b9102a7d4681c91784d137d60d71b ]
+
+The NTLMSSP_NEGOTIATE_VERSION flag only needs to be sent during
+the NTLMSSP NEGOTIATE (not the AUTH) request, so filter it out for
+NTLMSSP AUTH requests. See MS-NLMP 2.2.1.3
+
+This fixes a problem found by the gssntlmssp server.
+
+Link: https://github.com/gssapi/gss-ntlmssp/issues/95
+Fixes: 52d005337b2c ("smb3: send NTLMSSP version information")
+Acked-by: Roy Shterman <roy.shterman@gmail.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/sess.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c
+index 335c078c42fb5..c57ca2050b73f 100644
+--- a/fs/smb/client/sess.c
++++ b/fs/smb/client/sess.c
+@@ -1013,6 +1013,7 @@ int build_ntlmssp_smb3_negotiate_blob(unsigned char **pbuffer,
+ }
+
+
++/* See MS-NLMP 2.2.1.3 */
+ int build_ntlmssp_auth_blob(unsigned char **pbuffer,
+ u16 *buflen,
+ struct cifs_ses *ses,
+@@ -1047,7 +1048,8 @@ int build_ntlmssp_auth_blob(unsigned char **pbuffer,
+
+ flags = ses->ntlmssp->server_flags | NTLMSSP_REQUEST_TARGET |
+ NTLMSSP_NEGOTIATE_TARGET_INFO | NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED;
+-
++ /* we only send version information in ntlmssp negotiate, so do not set this flag */
++ flags = flags & ~NTLMSSP_NEGOTIATE_VERSION;
+ tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE);
+ sec_blob->NegotiateFlags = cpu_to_le32(flags);
+
+--
+2.40.1
+
--- /dev/null
+From c67e9b6b1bc54cf0cbbf563bd2f56fa906d0a888 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Jul 2023 13:55:00 -0700
+Subject: tmpfs: fix Documentation of noswap and huge mount options
+
+From: Hugh Dickins <hughd@google.com>
+
+[ Upstream commit 253e5df8b8f0145adb090f57c6f4e6efa52d738e ]
+
+The noswap mount option is surely not one of the three options for sizing:
+move its description down.
+
+The huge= mount option does not accept numeric values: those are just in
+an internal enum. Delete those numbers, and follow the manpage text more
+closely (but there's not yet any fadvise() or fcntl() which applies here).
+
+/sys/kernel/mm/transparent_hugepage/shmem_enabled is hard to describe, and
+barely relevant to mounting a tmpfs: just refer to transhuge.rst (while
+still using the words deny and force, to help as informal reminders).
+
+[rdunlap@infradead.org: fixup Docs table for huge mount options]
+ Link: https://lkml.kernel.org/r/20230725052333.26857-1-rdunlap@infradead.org
+Link: https://lkml.kernel.org/r/986cb0bf-9780-354-9bb-4bf57aadbab@google.com
+Signed-off-by: Hugh Dickins <hughd@google.com>
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Fixes: d0f5a85442d1 ("shmem: update documentation")
+Fixes: 2c6efe9cf2d7 ("shmem: add support to ignore swap")
+Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
+Cc: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/filesystems/tmpfs.rst | 47 ++++++++++++-----------------
+ 1 file changed, 20 insertions(+), 27 deletions(-)
+
+diff --git a/Documentation/filesystems/tmpfs.rst b/Documentation/filesystems/tmpfs.rst
+index f18f46be5c0c7..2cd8fa332feb7 100644
+--- a/Documentation/filesystems/tmpfs.rst
++++ b/Documentation/filesystems/tmpfs.rst
+@@ -84,8 +84,6 @@ nr_inodes The maximum number of inodes for this instance. The default
+ is half of the number of your physical RAM pages, or (on a
+ machine with highmem) the number of lowmem RAM pages,
+ whichever is the lower.
+-noswap Disables swap. Remounts must respect the original settings.
+- By default swap is enabled.
+ ========= ============================================================
+
+ These parameters accept a suffix k, m or g for kilo, mega and giga and
+@@ -99,36 +97,31 @@ mount with such options, since it allows any user with write access to
+ use up all the memory on the machine; but enhances the scalability of
+ that instance in a system with many CPUs making intensive use of it.
+
++tmpfs blocks may be swapped out, when there is a shortage of memory.
++tmpfs has a mount option to disable its use of swap:
++
++====== ===========================================================
++noswap Disables swap. Remounts must respect the original settings.
++ By default swap is enabled.
++====== ===========================================================
++
+ tmpfs also supports Transparent Huge Pages which requires a kernel
+ configured with CONFIG_TRANSPARENT_HUGEPAGE and with huge supported for
+ your system (has_transparent_hugepage(), which is architecture specific).
+ The mount options for this are:
+
+-====== ============================================================
+-huge=0 never: disables huge pages for the mount
+-huge=1 always: enables huge pages for the mount
+-huge=2 within_size: only allocate huge pages if the page will be
+- fully within i_size, also respect fadvise()/madvise() hints.
+-huge=3 advise: only allocate huge pages if requested with
+- fadvise()/madvise()
+-====== ============================================================
+-
+-There is a sysfs file which you can also use to control system wide THP
+-configuration for all tmpfs mounts, the file is:
+-
+-/sys/kernel/mm/transparent_hugepage/shmem_enabled
+-
+-This sysfs file is placed on top of THP sysfs directory and so is registered
+-by THP code. It is however only used to control all tmpfs mounts with one
+-single knob. Since it controls all tmpfs mounts it should only be used either
+-for emergency or testing purposes. The values you can set for shmem_enabled are:
+-
+-== ============================================================
+--1 deny: disables huge on shm_mnt and all mounts, for
+- emergency use
+--2 force: enables huge on shm_mnt and all mounts, w/o needing
+- option, for testing
+-== ============================================================
++================ ==============================================================
++huge=never Do not allocate huge pages. This is the default.
++huge=always Attempt to allocate huge page every time a new page is needed.
++huge=within_size Only allocate huge page if it will be fully within i_size.
++ Also respect madvise(2) hints.
++huge=advise Only allocate huge page if requested with madvise(2).
++================ ==============================================================
++
++See also Documentation/admin-guide/mm/transhuge.rst, which describes the
++sysfs file /sys/kernel/mm/transparent_hugepage/shmem_enabled: which can
++be used to deny huge pages on all tmpfs mounts in an emergency, or to
++force huge pages on all tmpfs mounts for testing.
+
+ tmpfs has a mount option to set the NUMA memory allocation policy for
+ all files in that instance (if CONFIG_NUMA is enabled) - which can be
+--
+2.40.1
+
--- /dev/null
+From 4f4cc99cf2bc95976c55317967e80464c2f010c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jul 2023 17:58:04 +0800
+Subject: tracing: Fix warning in trace_buffered_event_disable()
+
+From: Zheng Yejian <zhengyejian1@huawei.com>
+
+[ Upstream commit dea499781a1150d285c62b26659f62fb00824fce ]
+
+Warning happened in trace_buffered_event_disable() at
+ WARN_ON_ONCE(!trace_buffered_event_ref)
+
+ Call Trace:
+ ? __warn+0xa5/0x1b0
+ ? trace_buffered_event_disable+0x189/0x1b0
+ __ftrace_event_enable_disable+0x19e/0x3e0
+ free_probe_data+0x3b/0xa0
+ unregister_ftrace_function_probe_func+0x6b8/0x800
+ event_enable_func+0x2f0/0x3d0
+ ftrace_process_regex.isra.0+0x12d/0x1b0
+ ftrace_filter_write+0xe6/0x140
+ vfs_write+0x1c9/0x6f0
+ [...]
+
+The cause of the warning is in __ftrace_event_enable_disable(),
+trace_buffered_event_enable() was called once while
+trace_buffered_event_disable() was called twice.
+Reproduction script show as below, for analysis, see the comments:
+ ```
+ #!/bin/bash
+
+ cd /sys/kernel/tracing/
+
+ # 1. Register a 'disable_event' command, then:
+ # 1) SOFT_DISABLED_BIT was set;
+ # 2) trace_buffered_event_enable() was called first time;
+ echo 'cmdline_proc_show:disable_event:initcall:initcall_finish' > \
+ set_ftrace_filter
+
+ # 2. Enable the event registered, then:
+ # 1) SOFT_DISABLED_BIT was cleared;
+ # 2) trace_buffered_event_disable() was called first time;
+ echo 1 > events/initcall/initcall_finish/enable
+
+ # 3. Try to call into cmdline_proc_show(), then SOFT_DISABLED_BIT was
+ # set again!!!
+ cat /proc/cmdline
+
+ # 4. Unregister the 'disable_event' command, then:
+ # 1) SOFT_DISABLED_BIT was cleared again;
+ # 2) trace_buffered_event_disable() was called second time!!!
+ echo '!cmdline_proc_show:disable_event:initcall:initcall_finish' > \
+ set_ftrace_filter
+ ```
+
+To fix it, IIUC, we can change to call trace_buffered_event_enable() at
+fist time soft-mode enabled, and call trace_buffered_event_disable() at
+last time soft-mode disabled.
+
+Link: https://lore.kernel.org/linux-trace-kernel/20230726095804.920457-1-zhengyejian1@huawei.com
+
+Cc: <mhiramat@kernel.org>
+Fixes: 0fc1b09ff1ff ("tracing: Use temp buffer when filtering events")
+Signed-off-by: Zheng Yejian <zhengyejian1@huawei.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/trace_events.c | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
+index 57e539d479890..32f39eabc0716 100644
+--- a/kernel/trace/trace_events.c
++++ b/kernel/trace/trace_events.c
+@@ -611,7 +611,6 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,
+ {
+ struct trace_event_call *call = file->event_call;
+ struct trace_array *tr = file->tr;
+- unsigned long file_flags = file->flags;
+ int ret = 0;
+ int disable;
+
+@@ -635,6 +634,8 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,
+ break;
+ disable = file->flags & EVENT_FILE_FL_SOFT_DISABLED;
+ clear_bit(EVENT_FILE_FL_SOFT_MODE_BIT, &file->flags);
++ /* Disable use of trace_buffered_event */
++ trace_buffered_event_disable();
+ } else
+ disable = !(file->flags & EVENT_FILE_FL_SOFT_MODE);
+
+@@ -673,6 +674,8 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,
+ if (atomic_inc_return(&file->sm_ref) > 1)
+ break;
+ set_bit(EVENT_FILE_FL_SOFT_MODE_BIT, &file->flags);
++ /* Enable use of trace_buffered_event */
++ trace_buffered_event_enable();
+ }
+
+ if (!(file->flags & EVENT_FILE_FL_ENABLED)) {
+@@ -712,15 +715,6 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,
+ break;
+ }
+
+- /* Enable or disable use of trace_buffered_event */
+- if ((file_flags & EVENT_FILE_FL_SOFT_DISABLED) !=
+- (file->flags & EVENT_FILE_FL_SOFT_DISABLED)) {
+- if (file->flags & EVENT_FILE_FL_SOFT_DISABLED)
+- trace_buffered_event_enable();
+- else
+- trace_buffered_event_disable();
+- }
+-
+ return ret;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From ed9703aee2c0878430e84914639f011d824da9e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jul 2023 22:45:01 +0800
+Subject: ublk: fail to recover device if queue setup is interrupted
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 0c0cbd4ebc375ceebc75c89df04b74f215fab23a ]
+
+In ublk_ctrl_end_recovery(), if wait_for_completion_interruptible() is
+interrupted by signal, queues aren't setup successfully yet, so we
+have to fail UBLK_CMD_END_USER_RECOVERY, otherwise kernel oops can be
+triggered.
+
+Fixes: c732a852b419 ("ublk_drv: add START_USER_RECOVERY and END_USER_RECOVERY support")
+Reported-by: Stefano Garzarella <sgarzare@redhat.com>
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
+Link: https://lore.kernel.org/r/20230726144502.566785-3-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/ublk_drv.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
+index dc2856d1241fc..bf0711894c0a2 100644
+--- a/drivers/block/ublk_drv.c
++++ b/drivers/block/ublk_drv.c
+@@ -2107,7 +2107,9 @@ static int ublk_ctrl_end_recovery(struct ublk_device *ub,
+ pr_devel("%s: Waiting for new ubq_daemons(nr: %d) are ready, dev id %d...\n",
+ __func__, ub->dev_info.nr_hw_queues, header->dev_id);
+ /* wait until new ubq_daemon sending all FETCH_REQ */
+- wait_for_completion_interruptible(&ub->completion);
++ if (wait_for_completion_interruptible(&ub->completion))
++ return -EINTR;
++
+ pr_devel("%s: All new ubq_daemons(nr: %d) are ready, dev id %d\n",
+ __func__, ub->dev_info.nr_hw_queues, header->dev_id);
+
+--
+2.40.1
+
--- /dev/null
+From 3caabe5782f8d58cefa0cbfcfe78bc3837a8f148 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jul 2023 22:45:00 +0800
+Subject: ublk: fail to start device if queue setup is interrupted
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 53e7d08f6d6e214c40db1f51291bb2975c789dc2 ]
+
+In ublk_ctrl_start_dev(), if wait_for_completion_interruptible() is
+interrupted by signal, queues aren't setup successfully yet, so we
+have to fail UBLK_CMD_START_DEV, otherwise kernel oops can be triggered.
+
+Reported by German when working on qemu-storage-deamon which requires
+single thread ublk daemon.
+
+Fixes: 71f28f3136af ("ublk_drv: add io_uring based userspace block driver")
+Reported-by: German Maglione <gmaglione@redhat.com>
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20230726144502.566785-2-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/ublk_drv.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
+index 33d3298a0da16..dc2856d1241fc 100644
+--- a/drivers/block/ublk_drv.c
++++ b/drivers/block/ublk_drv.c
+@@ -1632,7 +1632,8 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub, struct io_uring_cmd *cmd)
+ if (ublksrv_pid <= 0)
+ return -EINVAL;
+
+- wait_for_completion_interruptible(&ub->completion);
++ if (wait_for_completion_interruptible(&ub->completion) != 0)
++ return -EINTR;
+
+ schedule_delayed_work(&ub->monitor_work, UBLK_DAEMON_MONITOR_PERIOD);
+
+--
+2.40.1
+
--- /dev/null
+From fc597c74eb5fe96949c16d8cbcaf649debc43fd5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jul 2023 22:45:02 +0800
+Subject: ublk: return -EINTR if breaking from waiting for existed users in
+ DEL_DEV
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 3e9dce80dbf91972aed972c743f539c396a34312 ]
+
+If user interrupts wait_event_interruptible() in ublk_ctrl_del_dev(),
+return -EINTR and let user know what happens.
+
+Fixes: 0abe39dec065 ("block: ublk: improve handling device deletion")
+Reported-by: Stefano Garzarella <sgarzare@redhat.com>
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
+Link: https://lore.kernel.org/r/20230726144502.566785-4-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/ublk_drv.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
+index bf0711894c0a2..e6b6e5eee4dea 100644
+--- a/drivers/block/ublk_drv.c
++++ b/drivers/block/ublk_drv.c
+@@ -1909,8 +1909,8 @@ static int ublk_ctrl_del_dev(struct ublk_device **p_ub)
+ * - the device number is freed already, we will not find this
+ * device via ublk_get_device_from_id()
+ */
+- wait_event_interruptible(ublk_idr_wq, ublk_idr_freed(idx));
+-
++ if (wait_event_interruptible(ublk_idr_wq, ublk_idr_freed(idx)))
++ return -EINTR;
+ return 0;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 39cce922448d82f5608498b5fada7237962d1b98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jul 2023 16:13:03 -0700
+Subject: xenbus: check xen_domain in xenbus_probe_initcall
+
+From: Stefano Stabellini <sstabellini@kernel.org>
+
+[ Upstream commit 0d8f7cc8057890db08c54fe610d8a94af59da082 ]
+
+The same way we already do in xenbus_init.
+Fixes the following warning:
+
+[ 352.175563] Trying to free already-free IRQ 0
+[ 352.177355] WARNING: CPU: 1 PID: 88 at kernel/irq/manage.c:1893 free_irq+0xbf/0x350
+[...]
+[ 352.213951] Call Trace:
+[ 352.214390] <TASK>
+[ 352.214717] ? __warn+0x81/0x170
+[ 352.215436] ? free_irq+0xbf/0x350
+[ 352.215906] ? report_bug+0x10b/0x200
+[ 352.216408] ? prb_read_valid+0x17/0x20
+[ 352.216926] ? handle_bug+0x44/0x80
+[ 352.217409] ? exc_invalid_op+0x13/0x60
+[ 352.217932] ? asm_exc_invalid_op+0x16/0x20
+[ 352.218497] ? free_irq+0xbf/0x350
+[ 352.218979] ? __pfx_xenbus_probe_thread+0x10/0x10
+[ 352.219600] xenbus_probe+0x7a/0x80
+[ 352.221030] xenbus_probe_thread+0x76/0xc0
+
+Fixes: 5b3353949e89 ("xen: add support for initializing xenstore later as HVM domain")
+Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
+Tested-by: Petr Mladek <pmladek@suse.com>
+Reviewed-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
+
+Link: https://lore.kernel.org/r/alpine.DEB.2.22.394.2307211609140.3118466@ubuntu-linux-20-04-desktop
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/xen/xenbus/xenbus_probe.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
+index 58b732dcbfb83..639bf628389ba 100644
+--- a/drivers/xen/xenbus/xenbus_probe.c
++++ b/drivers/xen/xenbus/xenbus_probe.c
+@@ -811,6 +811,9 @@ static int xenbus_probe_thread(void *unused)
+
+ static int __init xenbus_probe_initcall(void)
+ {
++ if (!xen_domain())
++ return -ENODEV;
++
+ /*
+ * Probe XenBus here in the XS_PV case, and also XS_HVM unless we
+ * need to wait for the platform PCI device to come up or
+--
+2.40.1
+