--- /dev/null
+From f3f8163c08aff8a5ff6640f2060bc163b6847ac6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Apr 2023 14:48:22 +0300
+Subject: accel/habanalabs: add pci health check during heartbeat
+
+From: Ofir Bitton <obitton@habana.ai>
+
+[ Upstream commit d8b9cea584661b30305cf341bf9f675dc0a25471 ]
+
+Currently upon a heartbeat failure, we don't know if the failure
+is due to firmware hang or due to a bad PCI link. Hence, we
+are reading a PCI config space register with a known value (vendor ID)
+so we will know which of the two possibilities caused the heartbeat
+failure.
+
+Signed-off-by: Ofir Bitton <obitton@habana.ai>
+Reviewed-by: Oded Gabbay <ogabbay@kernel.org>
+Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/habanalabs/common/device.c | 15 ++++++++++++++-
+ drivers/misc/habanalabs/common/habanalabs.h | 2 ++
+ drivers/misc/habanalabs/common/habanalabs_drv.c | 2 --
+ 3 files changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c
+index e0dca445abf14..9ee1b6abd8a05 100644
+--- a/drivers/misc/habanalabs/common/device.c
++++ b/drivers/misc/habanalabs/common/device.c
+@@ -870,6 +870,18 @@ static void device_early_fini(struct hl_device *hdev)
+ hdev->asic_funcs->early_fini(hdev);
+ }
+
++static bool is_pci_link_healthy(struct hl_device *hdev)
++{
++ u16 vendor_id;
++
++ if (!hdev->pdev)
++ return false;
++
++ pci_read_config_word(hdev->pdev, PCI_VENDOR_ID, &vendor_id);
++
++ return (vendor_id == PCI_VENDOR_ID_HABANALABS);
++}
++
+ static void hl_device_heartbeat(struct work_struct *work)
+ {
+ struct hl_device *hdev = container_of(work, struct hl_device,
+@@ -882,7 +894,8 @@ static void hl_device_heartbeat(struct work_struct *work)
+ goto reschedule;
+
+ if (hl_device_operational(hdev, NULL))
+- dev_err(hdev->dev, "Device heartbeat failed!\n");
++ dev_err(hdev->dev, "Device heartbeat failed! PCI link is %s\n",
++ is_pci_link_healthy(hdev) ? "healthy" : "broken");
+
+ hl_device_reset(hdev, HL_DRV_RESET_HARD | HL_DRV_RESET_HEARTBEAT);
+
+diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h
+index 58c95b13be69a..257b94cec6248 100644
+--- a/drivers/misc/habanalabs/common/habanalabs.h
++++ b/drivers/misc/habanalabs/common/habanalabs.h
+@@ -34,6 +34,8 @@
+ struct hl_device;
+ struct hl_fpriv;
+
++#define PCI_VENDOR_ID_HABANALABS 0x1da3
++
+ /* Use upper bits of mmap offset to store habana driver specific information.
+ * bits[63:59] - Encode mmap type
+ * bits[45:0] - mmap offset value
+diff --git a/drivers/misc/habanalabs/common/habanalabs_drv.c b/drivers/misc/habanalabs/common/habanalabs_drv.c
+index 112632afe7d53..ae3cab3f4aa55 100644
+--- a/drivers/misc/habanalabs/common/habanalabs_drv.c
++++ b/drivers/misc/habanalabs/common/habanalabs_drv.c
+@@ -54,8 +54,6 @@ module_param(boot_error_status_mask, ulong, 0444);
+ MODULE_PARM_DESC(boot_error_status_mask,
+ "Mask of the error status during device CPU boot (If bitX is cleared then error X is masked. Default all 1's)");
+
+-#define PCI_VENDOR_ID_HABANALABS 0x1da3
+-
+ #define PCI_IDS_GOYA 0x0001
+ #define PCI_IDS_GAUDI 0x1000
+ #define PCI_IDS_GAUDI_SEC 0x1010
+--
+2.40.1
+
--- /dev/null
+From e3646ab4ec4442162e01b6ce0c18cdf9ef1f771d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Jul 2023 11:10:16 +0800
+Subject: ALSA: hda: fix a possible null-pointer dereference due to data race
+ in snd_hdac_regmap_sync()
+
+From: Tuo Li <islituo@gmail.com>
+
+[ Upstream commit 1f4a08fed450db87fbb5ff5105354158bdbe1a22 ]
+
+The variable codec->regmap is often protected by the lock
+codec->regmap_lock when is accessed. However, it is accessed without
+holding the lock when is accessed in snd_hdac_regmap_sync():
+
+ if (codec->regmap)
+
+In my opinion, this may be a harmful race, because if codec->regmap is
+set to NULL right after the condition is checked, a null-pointer
+dereference can occur in the called function regcache_sync():
+
+ map->lock(map->lock_arg); --> Line 360 in drivers/base/regmap/regcache.c
+
+To fix this possible null-pointer dereference caused by data race, the
+mutex_lock coverage is extended to protect the if statement as well as the
+function call to regcache_sync().
+
+[ Note: the lack of the regmap_lock itself is harmless for the current
+ codec driver implementations, as snd_hdac_regmap_sync() is only for
+ PM runtime resume that is prohibited during the codec probe.
+ But the change makes the whole code more consistent, so it's merged
+ as is -- tiwai ]
+
+Reported-by: BassCheck <bass@buaa.edu.cn>
+Signed-off-by: Tuo Li <islituo@gmail.com>
+Link: https://lore.kernel.org/r/20230703031016.1184711-1-islituo@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/hda/hdac_regmap.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/sound/hda/hdac_regmap.c b/sound/hda/hdac_regmap.c
+index fe3587547cfec..39610a15bcc98 100644
+--- a/sound/hda/hdac_regmap.c
++++ b/sound/hda/hdac_regmap.c
+@@ -597,10 +597,9 @@ EXPORT_SYMBOL_GPL(snd_hdac_regmap_update_raw_once);
+ */
+ void snd_hdac_regmap_sync(struct hdac_device *codec)
+ {
+- if (codec->regmap) {
+- mutex_lock(&codec->regmap_lock);
++ mutex_lock(&codec->regmap_lock);
++ if (codec->regmap)
+ regcache_sync(codec->regmap);
+- mutex_unlock(&codec->regmap_lock);
+- }
++ mutex_unlock(&codec->regmap_lock);
+ }
+ EXPORT_SYMBOL_GPL(snd_hdac_regmap_sync);
+--
+2.40.1
+
--- /dev/null
+From 164bdd5d306f079d559462d3d379c8e9244045ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Jul 2023 16:46:16 +1200
+Subject: ALSA: hda/realtek: Add quirk for ASUS ROG GA402X
+
+From: Luke D. Jones <luke@ljones.dev>
+
+[ Upstream commit 9abc77fb144fe916fd2f592dc4b8c7bade02e58a ]
+
+Adds the required quirk to enable the Cirrus amp and correct pins
+on the ASUS ROG GA402X series which uses an I2C connected Cirrus amp.
+
+While this works if the related _DSD properties are made available, these
+aren't included in the ACPI of these laptops (yet).
+
+Signed-off-by: Luke D. Jones <luke@ljones.dev>
+Link: https://lore.kernel.org/r/20230704044619.19343-3-luke@ljones.dev
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index b290391314873..b0cee0a361bfb 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -9617,6 +9617,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
+ SND_PCI_QUIRK(0x1043, 0x1433, "ASUS GX650P", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC),
++ SND_PCI_QUIRK(0x1043, 0x1463, "Asus GA402X", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1473, "ASUS GU604V", ALC285_FIXUP_ASUS_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1483, "ASUS GU603V", ALC285_FIXUP_ASUS_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
+--
+2.40.1
+
--- /dev/null
+From 1cc61ff6018b120b17aecbf693177c16181153a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Jul 2023 16:46:15 +1200
+Subject: ALSA: hda/realtek: Add quirk for ASUS ROG GX650P
+
+From: Luke D. Jones <luke@ljones.dev>
+
+[ Upstream commit 8cc87c055d28320e5fa5457922f43bc07dec58bd ]
+
+Adds the required quirk to enable the Cirrus amp and correct pins
+on the ASUS ROG GV601V series which uses an I2C connected Cirrus amp.
+
+While this works if the related _DSD properties are made available, these
+aren't included in the ACPI of these laptops (yet).
+
+Signed-off-by: Luke D. Jones <luke@ljones.dev>
+Link: https://lore.kernel.org/r/20230704044619.19343-2-luke@ljones.dev
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 923b8e0c9efe3..b290391314873 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -7081,6 +7081,8 @@ enum {
+ ALC285_FIXUP_SPEAKER2_TO_DAC1,
+ ALC285_FIXUP_ASUS_SPEAKER2_TO_DAC1,
+ ALC285_FIXUP_ASUS_HEADSET_MIC,
++ ALC285_FIXUP_ASUS_I2C_SPEAKER2_TO_DAC1,
++ ALC285_FIXUP_ASUS_I2C_HEADSET_MIC,
+ ALC280_FIXUP_HP_HEADSET_MIC,
+ ALC221_FIXUP_HP_FRONT_MIC,
+ ALC292_FIXUP_TPT460,
+@@ -8073,6 +8075,22 @@ static const struct hda_fixup alc269_fixups[] = {
+ .chained = true,
+ .chain_id = ALC285_FIXUP_ASUS_SPEAKER2_TO_DAC1
+ },
++ [ALC285_FIXUP_ASUS_I2C_SPEAKER2_TO_DAC1] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = alc285_fixup_speaker2_to_dac1,
++ .chained = true,
++ .chain_id = ALC287_FIXUP_CS35L41_I2C_2
++ },
++ [ALC285_FIXUP_ASUS_I2C_HEADSET_MIC] = {
++ .type = HDA_FIXUP_PINS,
++ .v.pins = (const struct hda_pintbl[]) {
++ { 0x19, 0x03a11050 },
++ { 0x1b, 0x03a11c30 },
++ { }
++ },
++ .chained = true,
++ .chain_id = ALC285_FIXUP_ASUS_I2C_SPEAKER2_TO_DAC1
++ },
+ [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
+ .type = HDA_FIXUP_PINS,
+ .v.pins = (const struct hda_pintbl[]) {
+@@ -9598,6 +9616,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1043, 0x1313, "Asus K42JZ", ALC269VB_FIXUP_ASUS_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
++ SND_PCI_QUIRK(0x1043, 0x1433, "ASUS GX650P", ALC285_FIXUP_ASUS_I2C_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1473, "ASUS GU604V", ALC285_FIXUP_ASUS_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1483, "ASUS GU603V", ALC285_FIXUP_ASUS_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
+--
+2.40.1
+
--- /dev/null
+From de69862664a25ed0d17456a4d21ccf217f6b7ccb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 10:33:23 +1200
+Subject: ALSA: hda/realtek: Add quirk for ASUS ROG GZ301V
+
+From: Luke D. Jones <luke@ljones.dev>
+
+[ Upstream commit 5251605f4d297a0eb5d3b7f39f9dcee9e4d0115a ]
+
+Adds the required quirk to enable the Cirrus amp and correct pins
+on the ASUS ROG GZ301V series which uses an SPI connected Cirrus amp.
+
+While this works if the related _DSD properties are made available, these
+aren't included in the ACPI of these laptops (yet).
+
+Signed-off-by: Luke D. Jones <luke@ljones.dev>
+Link: https://lore.kernel.org/r/20230706223323.30871-2-luke@ljones.dev
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index b0cee0a361bfb..526ec8cae9437 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -9621,6 +9621,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1043, 0x1473, "ASUS GU604V", ALC285_FIXUP_ASUS_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1483, "ASUS GU603V", ALC285_FIXUP_ASUS_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
++ SND_PCI_QUIRK(0x1043, 0x1573, "ASUS GZ301V", ALC285_FIXUP_ASUS_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK),
+ SND_PCI_QUIRK(0x1043, 0x1683, "ASUS UM3402YAR", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401),
+--
+2.40.1
+
--- /dev/null
+From d2c598f3c56af5cf6b50a430f2b9c9a57560868d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jun 2023 11:17:14 -0500
+Subject: ALSA: hda/realtek: Add quirks for ROG ALLY CS35l41 audio
+
+From: Matthew Anderson <ruinairas1992@gmail.com>
+
+[ Upstream commit 724418b84e6248cd27599607b7e5fac365b8e3f5 ]
+
+This requires a patched ACPI table or a firmware from ASUS to work because
+the system does not come with the _DSD field for the CSC3551.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=217550
+Signed-off-by: Matthew Anderson <ruinairas1992@gmail.com>
+Tested-by: Philip Mueller <philm@manjaro.org>
+Link: https://lore.kernel.org/r/20230621161714.9442-1-ruinairas1992@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 46 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index f93b68a2a8393..f3c5940b032ff 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -7136,6 +7136,10 @@ enum {
+ ALC294_FIXUP_ASUS_DUAL_SPK,
+ ALC285_FIXUP_THINKPAD_X1_GEN7,
+ ALC285_FIXUP_THINKPAD_HEADSET_JACK,
++ ALC294_FIXUP_ASUS_ALLY,
++ ALC294_FIXUP_ASUS_ALLY_PINS,
++ ALC294_FIXUP_ASUS_ALLY_VERBS,
++ ALC294_FIXUP_ASUS_ALLY_SPEAKER,
+ ALC294_FIXUP_ASUS_HPE,
+ ALC294_FIXUP_ASUS_COEF_1B,
+ ALC294_FIXUP_ASUS_GX502_HP,
+@@ -8450,6 +8454,47 @@ static const struct hda_fixup alc269_fixups[] = {
+ .chained = true,
+ .chain_id = ALC294_FIXUP_SPK2_TO_DAC1
+ },
++ [ALC294_FIXUP_ASUS_ALLY] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = cs35l41_fixup_i2c_two,
++ .chained = true,
++ .chain_id = ALC294_FIXUP_ASUS_ALLY_PINS
++ },
++ [ALC294_FIXUP_ASUS_ALLY_PINS] = {
++ .type = HDA_FIXUP_PINS,
++ .v.pins = (const struct hda_pintbl[]) {
++ { 0x19, 0x03a11050 },
++ { 0x1a, 0x03a11c30 },
++ { 0x21, 0x03211420 },
++ { }
++ },
++ .chained = true,
++ .chain_id = ALC294_FIXUP_ASUS_ALLY_VERBS
++ },
++ [ALC294_FIXUP_ASUS_ALLY_VERBS] = {
++ .type = HDA_FIXUP_VERBS,
++ .v.verbs = (const struct hda_verb[]) {
++ { 0x20, AC_VERB_SET_COEF_INDEX, 0x45 },
++ { 0x20, AC_VERB_SET_PROC_COEF, 0x5089 },
++ { 0x20, AC_VERB_SET_COEF_INDEX, 0x46 },
++ { 0x20, AC_VERB_SET_PROC_COEF, 0x0004 },
++ { 0x20, AC_VERB_SET_COEF_INDEX, 0x47 },
++ { 0x20, AC_VERB_SET_PROC_COEF, 0xa47a },
++ { 0x20, AC_VERB_SET_COEF_INDEX, 0x49 },
++ { 0x20, AC_VERB_SET_PROC_COEF, 0x0049},
++ { 0x20, AC_VERB_SET_COEF_INDEX, 0x4a },
++ { 0x20, AC_VERB_SET_PROC_COEF, 0x201b },
++ { 0x20, AC_VERB_SET_COEF_INDEX, 0x6b },
++ { 0x20, AC_VERB_SET_PROC_COEF, 0x4278},
++ { }
++ },
++ .chained = true,
++ .chain_id = ALC294_FIXUP_ASUS_ALLY_SPEAKER
++ },
++ [ALC294_FIXUP_ASUS_ALLY_SPEAKER] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = alc285_fixup_speaker2_to_dac1,
++ },
+ [ALC285_FIXUP_THINKPAD_X1_GEN7] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc285_fixup_thinkpad_x1_gen7,
+@@ -9562,6 +9607,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
+ SND_PCI_QUIRK(0x1043, 0x1740, "ASUS UX430UA", ALC295_FIXUP_ASUS_DACS),
+ SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK),
++ SND_PCI_QUIRK(0x1043, 0x17f3, "ROG Ally RC71L_RC71L", ALC294_FIXUP_ASUS_ALLY),
+ SND_PCI_QUIRK(0x1043, 0x1881, "ASUS Zephyrus S/M", ALC294_FIXUP_ASUS_GX502_PINS),
+ SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC),
+--
+2.40.1
+
--- /dev/null
+From a585f3cb4d4741592de3a131f337768db89985e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Jul 2023 10:17:51 +0800
+Subject: ALSA: hda/realtek: Add quirks for Unis H3C Desktop B760 & Q760
+
+From: dengxiang <dengxiang@nfschina.com>
+
+[ Upstream commit 73f1c75d5e6bd8ce2a887ef493a66ad1b16ed704 ]
+
+These models use NSIWAY amplifiers for internal speaker, but cannot put
+sound outside from these amplifiers. So eapd verbs are needed to initialize
+the amplifiers. They can be added during boot to get working sound out
+of internal speaker.
+
+Signed-off-by: dengxiang <dengxiang@nfschina.com>
+Link: https://lore.kernel.org/r/20230703021751.2945750-1-dengxiang@nfschina.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index f3c5940b032ff..923b8e0c9efe3 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -11314,6 +11314,7 @@ enum {
+ ALC897_FIXUP_HP_HSMIC_VERB,
+ ALC897_FIXUP_LENOVO_HEADSET_MODE,
+ ALC897_FIXUP_HEADSET_MIC_PIN2,
++ ALC897_FIXUP_UNIS_H3C_X500S,
+ };
+
+ static const struct hda_fixup alc662_fixups[] = {
+@@ -11753,6 +11754,13 @@ static const struct hda_fixup alc662_fixups[] = {
+ .chained = true,
+ .chain_id = ALC897_FIXUP_LENOVO_HEADSET_MODE
+ },
++ [ALC897_FIXUP_UNIS_H3C_X500S] = {
++ .type = HDA_FIXUP_VERBS,
++ .v.verbs = (const struct hda_verb[]) {
++ { 0x14, AC_VERB_SET_EAPD_BTLENABLE, 0 },
++ {}
++ },
++ },
+ };
+
+ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+@@ -11914,6 +11922,7 @@ static const struct hda_model_fixup alc662_fixup_models[] = {
+ {.id = ALC662_FIXUP_USI_HEADSET_MODE, .name = "usi-headset"},
+ {.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
+ {.id = ALC669_FIXUP_ACER_ASPIRE_ETHOS, .name = "aspire-ethos"},
++ {.id = ALC897_FIXUP_UNIS_H3C_X500S, .name = "unis-h3c-x500s"},
+ {}
+ };
+
+--
+2.40.1
+
--- /dev/null
+From db21c0732460f1bab090a6477a4bbb9b8114b55a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Jan 2023 20:12:19 +0000
+Subject: apparmor: fix use of strcpy in policy_unpack_test
+
+From: Rae Moar <rmoar@google.com>
+
+[ Upstream commit b54aebd4411134b525a82d663a26b2f135ecb7e8 ]
+
+Replace the use of strcpy() in build_aa_ext_struct() in
+policy_unpack_test.c with strscpy().
+
+strscpy() is the safer method to use to ensure the buffer does not
+overflow. This was found by kernel test robot:
+https://lore.kernel.org/all/202301040348.NbfVsXO0-lkp@intel.com/.
+
+Reported-by: kernel test robot <lkp@intel.com>
+
+Signed-off-by: Rae Moar <rmoar@google.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/policy_unpack_test.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/security/apparmor/policy_unpack_test.c b/security/apparmor/policy_unpack_test.c
+index 0a969b2e03dba..64ddea559f9ac 100644
+--- a/security/apparmor/policy_unpack_test.c
++++ b/security/apparmor/policy_unpack_test.c
+@@ -66,31 +66,30 @@ static struct aa_ext *build_aa_ext_struct(struct policy_unpack_fixture *puf,
+
+ *buf = AA_NAME;
+ *(buf + 1) = strlen(TEST_STRING_NAME) + 1;
+- strcpy(buf + 3, TEST_STRING_NAME);
++ strscpy(buf + 3, TEST_STRING_NAME, e->end - (void *)(buf + 3));
+
+ buf = e->start + TEST_STRING_BUF_OFFSET;
+ *buf = AA_STRING;
+ *(buf + 1) = strlen(TEST_STRING_DATA) + 1;
+- strcpy(buf + 3, TEST_STRING_DATA);
+-
++ strscpy(buf + 3, TEST_STRING_DATA, e->end - (void *)(buf + 3));
+ buf = e->start + TEST_NAMED_U32_BUF_OFFSET;
+ *buf = AA_NAME;
+ *(buf + 1) = strlen(TEST_U32_NAME) + 1;
+- strcpy(buf + 3, TEST_U32_NAME);
++ strscpy(buf + 3, TEST_U32_NAME, e->end - (void *)(buf + 3));
+ *(buf + 3 + strlen(TEST_U32_NAME) + 1) = AA_U32;
+ *((u32 *)(buf + 3 + strlen(TEST_U32_NAME) + 2)) = TEST_U32_DATA;
+
+ buf = e->start + TEST_NAMED_U64_BUF_OFFSET;
+ *buf = AA_NAME;
+ *(buf + 1) = strlen(TEST_U64_NAME) + 1;
+- strcpy(buf + 3, TEST_U64_NAME);
++ strscpy(buf + 3, TEST_U64_NAME, e->end - (void *)(buf + 3));
+ *(buf + 3 + strlen(TEST_U64_NAME) + 1) = AA_U64;
+ *((u64 *)(buf + 3 + strlen(TEST_U64_NAME) + 2)) = TEST_U64_DATA;
+
+ buf = e->start + TEST_NAMED_BLOB_BUF_OFFSET;
+ *buf = AA_NAME;
+ *(buf + 1) = strlen(TEST_BLOB_NAME) + 1;
+- strcpy(buf + 3, TEST_BLOB_NAME);
++ strscpy(buf + 3, TEST_BLOB_NAME, e->end - (void *)(buf + 3));
+ *(buf + 3 + strlen(TEST_BLOB_NAME) + 1) = AA_BLOB;
+ *(buf + 3 + strlen(TEST_BLOB_NAME) + 2) = TEST_BLOB_DATA_SIZE;
+ memcpy(buf + 3 + strlen(TEST_BLOB_NAME) + 6,
+@@ -99,7 +98,7 @@ static struct aa_ext *build_aa_ext_struct(struct policy_unpack_fixture *puf,
+ buf = e->start + TEST_NAMED_ARRAY_BUF_OFFSET;
+ *buf = AA_NAME;
+ *(buf + 1) = strlen(TEST_ARRAY_NAME) + 1;
+- strcpy(buf + 3, TEST_ARRAY_NAME);
++ strscpy(buf + 3, TEST_ARRAY_NAME, e->end - (void *)(buf + 3));
+ *(buf + 3 + strlen(TEST_ARRAY_NAME) + 1) = AA_ARRAY;
+ *((u16 *)(buf + 3 + strlen(TEST_ARRAY_NAME) + 2)) = TEST_ARRAY_SIZE;
+
+--
+2.40.1
+
--- /dev/null
+From 0f4a01b067e85ff3b845ac34ed62710a0dbc0517 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 14:03:44 +0200
+Subject: ARM: dts: imx6dl: prtrvt, prtvt7, prti6q, prtwd2: fix USB related
+ warnings
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+[ Upstream commit 1d14bd943fa2bbdfda1efbcc080b298fed5f1803 ]
+
+Fix USB-related warnings in prtrvt, prtvt7, prti6q and prtwd2 device trees
+by disabling unused usbphynop1 and usbphynop2 USB PHYs and providing proper
+configuration for the over-current detection. This fixes the following
+warnings with the current kernel:
+ usb_phy_generic usbphynop1: dummy supplies not allowed for exclusive requests
+ usb_phy_generic usbphynop2: dummy supplies not allowed for exclusive requests
+ imx_usb 2184200.usb: No over current polarity defined
+
+By the way, fix over-current detection on usbotg port for prtvt7, prti6q
+and prtwd2 boards. Only prtrvt do not have OC on USB OTG port.
+
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6dl-prtrvt.dts | 4 ++++
+ arch/arm/boot/dts/imx6qdl-prti6q.dtsi | 11 ++++++++++-
+ 2 files changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/imx6dl-prtrvt.dts b/arch/arm/boot/dts/imx6dl-prtrvt.dts
+index 56bb1ca56a2df..36b031236e475 100644
+--- a/arch/arm/boot/dts/imx6dl-prtrvt.dts
++++ b/arch/arm/boot/dts/imx6dl-prtrvt.dts
+@@ -124,6 +124,10 @@ &usbh1 {
+ status = "disabled";
+ };
+
++&usbotg {
++ disable-over-current;
++};
++
+ &vpu {
+ status = "disabled";
+ };
+diff --git a/arch/arm/boot/dts/imx6qdl-prti6q.dtsi b/arch/arm/boot/dts/imx6qdl-prti6q.dtsi
+index f0db0d4471f40..36f84f4da6b0d 100644
+--- a/arch/arm/boot/dts/imx6qdl-prti6q.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-prti6q.dtsi
+@@ -69,6 +69,7 @@ &usbh1 {
+ vbus-supply = <®_usb_h1_vbus>;
+ phy_type = "utmi";
+ dr_mode = "host";
++ disable-over-current;
+ status = "okay";
+ };
+
+@@ -78,10 +79,18 @@ &usbotg {
+ pinctrl-0 = <&pinctrl_usbotg>;
+ phy_type = "utmi";
+ dr_mode = "host";
+- disable-over-current;
++ over-current-active-low;
+ status = "okay";
+ };
+
++&usbphynop1 {
++ status = "disabled";
++};
++
++&usbphynop2 {
++ status = "disabled";
++};
++
+ &usdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+--
+2.40.1
+
--- /dev/null
+From a02aea51013dae8732fe3ac8ec07a2133c8ad197 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 10:28:33 +0800
+Subject: ARM: dts: nxp/imx6sll: fix wrong property name in usbphy node
+
+From: Xu Yang <xu.yang_2@nxp.com>
+
+[ Upstream commit ee70b908f77a9d8f689dea986f09e6d7dc481934 ]
+
+Property name "phy-3p0-supply" is used instead of "phy-reg_3p0-supply".
+
+Fixes: 9f30b6b1a957 ("ARM: dts: imx: Add basic dtsi file for imx6sll")
+cc: <stable@vger.kernel.org>
+Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6sll.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi
+index 2873369a57c02..3659fd5ecfa62 100644
+--- a/arch/arm/boot/dts/imx6sll.dtsi
++++ b/arch/arm/boot/dts/imx6sll.dtsi
+@@ -552,7 +552,7 @@ usbphy2: usb-phy@20ca000 {
+ reg = <0x020ca000 0x1000>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6SLL_CLK_USBPHY2>;
+- phy-reg_3p0-supply = <®_3p0>;
++ phy-3p0-supply = <®_3p0>;
+ fsl,anatop = <&anatop>;
+ };
+
+--
+2.40.1
+
--- /dev/null
+From daa519c82b09959891adaae81c8949c3d33b6826 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 16:37:58 +0530
+Subject: ASoC: amd: vangogh: Add check for acp config flags in vangogh
+ platform
+
+From: Venkata Prasad Potturu <venkataprasad.potturu@amd.com>
+
+[ Upstream commit e89f45edb747ed88e97a5771dd6d3dd1eb517873 ]
+
+We have SOF and generic ACP support enabled for Vangogh platform
+on some machines. Since we have same PCI id used for probing,
+add check for machine configuration flag to avoid conflict with
+newer pci drivers. Such machine flag has been initialized via
+dmi match on few Vangogh based machines. If no flag is
+specified probe and register older platform device.
+
+Signed-off-by: Venkata Prasad Potturu <venkataprasad.potturu@amd.com>
+Link: https://lore.kernel.org/r/20230530110802.674939-1-venkataprasad.potturu@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/vangogh/acp5x.h | 2 ++
+ sound/soc/amd/vangogh/pci-acp5x.c | 7 ++++++-
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/amd/vangogh/acp5x.h b/sound/soc/amd/vangogh/acp5x.h
+index bd9f1c5684d17..ac1936a8c43ff 100644
+--- a/sound/soc/amd/vangogh/acp5x.h
++++ b/sound/soc/amd/vangogh/acp5x.h
+@@ -147,6 +147,8 @@ static inline void acp_writel(u32 val, void __iomem *base_addr)
+ writel(val, base_addr - ACP5x_PHY_BASE_ADDRESS);
+ }
+
++int snd_amd_acp_find_config(struct pci_dev *pci);
++
+ static inline u64 acp_get_byte_count(struct i2s_stream_instance *rtd,
+ int direction)
+ {
+diff --git a/sound/soc/amd/vangogh/pci-acp5x.c b/sound/soc/amd/vangogh/pci-acp5x.c
+index e0df17c88e8e0..c4634a8a17cdc 100644
+--- a/sound/soc/amd/vangogh/pci-acp5x.c
++++ b/sound/soc/amd/vangogh/pci-acp5x.c
+@@ -125,10 +125,15 @@ static int snd_acp5x_probe(struct pci_dev *pci,
+ {
+ struct acp5x_dev_data *adata;
+ struct platform_device_info pdevinfo[ACP5x_DEVS];
+- unsigned int irqflags;
++ unsigned int irqflags, flag;
+ int ret, i;
+ u32 addr, val;
+
++ /* Return if acp config flag is defined */
++ flag = snd_amd_acp_find_config(pci);
++ if (flag)
++ return -ENODEV;
++
+ irqflags = IRQF_SHARED;
+ if (pci->revision != 0x50)
+ return -ENODEV;
+--
+2.40.1
+
--- /dev/null
+From 0ea6d4dcbfcd5313b93a9c3b12dd2e0e3352db0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 May 2023 12:33:05 -0500
+Subject: ASoC: Intel: sof_sdw: add quirk for LNL RVP
+
+From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+
+[ Upstream commit dfe25fea968dc4884e12d471c8263f0f611b380a ]
+
+We should use RT711_JD2_100K for on board rt711
+
+Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com
+Link: https://lore.kernel.org/r/20230512173305.65399-9-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/sof_sdw.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
+index 7f9940c722a3c..0cf9efec46ce2 100644
+--- a/sound/soc/intel/boards/sof_sdw.c
++++ b/sound/soc/intel/boards/sof_sdw.c
+@@ -382,6 +382,15 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
+ },
+ .driver_data = (void *)(RT711_JD2_100K),
+ },
++ /* LunarLake devices */
++ {
++ .callback = sof_sdw_quirk_cb,
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Lunar Lake Client Platform"),
++ },
++ .driver_data = (void *)(RT711_JD2_100K),
++ },
+ {}
+ };
+
+--
+2.40.1
+
--- /dev/null
+From a061c74fe81a9d07de142a0574d337acb76d6b24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 May 2023 12:33:00 -0500
+Subject: ASoC: Intel: sof_sdw: add quirk for MTL RVP
+
+From: Bard Liao <yung-chuan.liao@linux.intel.com>
+
+[ Upstream commit 289e1df00e49a229a1c924c059242e759a552f01 ]
+
+We should use RT711_JD2_100K for on board rt711.
+
+Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com
+Link: https://lore.kernel.org/r/20230512173305.65399-4-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/sof_sdw.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
+index a37c85d301471..7f9940c722a3c 100644
+--- a/sound/soc/intel/boards/sof_sdw.c
++++ b/sound/soc/intel/boards/sof_sdw.c
+@@ -374,6 +374,14 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
+ },
+ .driver_data = (void *)(RT711_JD1),
+ },
++ {
++ .callback = sof_sdw_quirk_cb,
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Meteor Lake Client Platform"),
++ },
++ .driver_data = (void *)(RT711_JD2_100K),
++ },
+ {}
+ };
+
+--
+2.40.1
+
--- /dev/null
+From 840c69ce4efaf34fcc64c0946edd7dbe4520b8ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Jun 2023 15:22:24 -0500
+Subject: ASoC: Intel: sof_sdw: Add support for Rex soundwire
+
+From: Uday M Bhat <uday.m.bhat@intel.com>
+
+[ Upstream commit 164e5dc17525181c05563f0a06796f1a363801d5 ]
+
+Add rex entry in the soundwire quirk table
+
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Signed-off-by: Yong Zhi <yong.zhi@intel.com>
+Signed-off-by: Uday M Bhat <uday.m.bhat@intel.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20230602202225.249209-28-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/sof_sdw.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
+index 0cf9efec46ce2..064b6feb76167 100644
+--- a/sound/soc/intel/boards/sof_sdw.c
++++ b/sound/soc/intel/boards/sof_sdw.c
+@@ -382,6 +382,14 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
+ },
+ .driver_data = (void *)(RT711_JD2_100K),
+ },
++ {
++ .callback = sof_sdw_quirk_cb,
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Google"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Rex"),
++ },
++ .driver_data = (void *)(SOF_SDW_PCH_DMIC),
++ },
+ /* LunarLake devices */
+ {
+ .callback = sof_sdw_quirk_cb,
+--
+2.40.1
+
--- /dev/null
+From a93e81b7b7234202d513470d8be0cf77b8d8ad9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Jun 2023 15:22:04 -0500
+Subject: ASoC: Intel: sof_sdw_rt_sdca_jack_common: test SOF_JACK_JDSRC in
+ _exit
+
+From: Bard Liao <yung-chuan.liao@linux.intel.com>
+
+[ Upstream commit 526a1876fc48e2d0c0ea8ad63b58bdb2cc13047f ]
+
+if (!SOF_RT711_JDSRC(sof_sdw_quirk)) is tested in rt711_sdca_add_codec_
+device_props(), and we don't add software node to the device if jack
+source is not set. We need to do the same test in
+sof_sdw_rt711_sdca_exit(), and avoid removing software node if jack
+source is not set.
+
+Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20230602202225.249209-8-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/sof_sdw_rt711_sdca.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sound/soc/intel/boards/sof_sdw_rt711_sdca.c b/sound/soc/intel/boards/sof_sdw_rt711_sdca.c
+index 7f16304d025be..cf8b9793fe0e5 100644
+--- a/sound/soc/intel/boards/sof_sdw_rt711_sdca.c
++++ b/sound/soc/intel/boards/sof_sdw_rt711_sdca.c
+@@ -143,6 +143,9 @@ int sof_sdw_rt711_sdca_exit(struct snd_soc_card *card, struct snd_soc_dai_link *
+ if (!ctx->headset_codec_dev)
+ return 0;
+
++ if (!SOF_RT711_JDSRC(sof_sdw_quirk))
++ return 0;
++
+ device_remove_software_node(ctx->headset_codec_dev);
+ put_device(ctx->headset_codec_dev);
+
+--
+2.40.1
+
--- /dev/null
+From be3421abb0da2eb34ba550a790776aa3922160c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 May 2023 12:50:01 +0530
+Subject: ASoC: SOF: amd: Add pci revision id check
+
+From: Venkata Prasad Potturu <venkataprasad.potturu@amd.com>
+
+[ Upstream commit 1d4a84632b90d88316986b05bcdfe715399a33db ]
+
+Add pci revision id check for renoir and rembrandt platforms.
+
+Signed-off-by: Venkata Prasad Potturu <venkataprasad.potturu@amd.com>
+Link: https://lore.kernel.org/r/20230523072009.2379198-1-venkataprasad.potturu@amd.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/amd/acp.h | 3 +++
+ sound/soc/sof/amd/pci-rmb.c | 3 +++
+ sound/soc/sof/amd/pci-rn.c | 3 +++
+ 3 files changed, 9 insertions(+)
+
+diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h
+index dd3c072d01721..14148c311f504 100644
+--- a/sound/soc/sof/amd/acp.h
++++ b/sound/soc/sof/amd/acp.h
+@@ -54,6 +54,9 @@
+
+ #define ACP_DSP_TO_HOST_IRQ 0x04
+
++#define ACP_RN_PCI_ID 0x01
++#define ACP_RMB_PCI_ID 0x6F
++
+ #define HOST_BRIDGE_CZN 0x1630
+ #define HOST_BRIDGE_RMB 0x14B5
+ #define ACP_SHA_STAT 0x8000
+diff --git a/sound/soc/sof/amd/pci-rmb.c b/sound/soc/sof/amd/pci-rmb.c
+index 4e1de462b431b..5698d910b26f3 100644
+--- a/sound/soc/sof/amd/pci-rmb.c
++++ b/sound/soc/sof/amd/pci-rmb.c
+@@ -90,6 +90,9 @@ static int acp_pci_rmb_probe(struct pci_dev *pci, const struct pci_device_id *pc
+ unsigned int flag, i, addr;
+ int ret;
+
++ if (pci->revision != ACP_RMB_PCI_ID)
++ return -ENODEV;
++
+ flag = snd_amd_acp_find_config(pci);
+ if (flag != FLAG_AMD_SOF && flag != FLAG_AMD_SOF_ONLY_DMIC)
+ return -ENODEV;
+diff --git a/sound/soc/sof/amd/pci-rn.c b/sound/soc/sof/amd/pci-rn.c
+index fca40b261671b..9189f63632789 100644
+--- a/sound/soc/sof/amd/pci-rn.c
++++ b/sound/soc/sof/amd/pci-rn.c
+@@ -90,6 +90,9 @@ static int acp_pci_rn_probe(struct pci_dev *pci, const struct pci_device_id *pci
+ unsigned int flag, i, addr;
+ int ret;
+
++ if (pci->revision != ACP_RN_PCI_ID)
++ return -ENODEV;
++
+ flag = snd_amd_acp_find_config(pci);
+ if (flag != FLAG_AMD_SOF && flag != FLAG_AMD_SOF_ONLY_DMIC)
+ return -ENODEV;
+--
+2.40.1
+
--- /dev/null
+From 801f194895e4d72449f48d0e815a0cf48bda187a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 12:00:34 +0200
+Subject: ASoC: SOF: core: Free the firmware trace before calling
+ snd_sof_shutdown()
+
+From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+
+[ Upstream commit d389dcb3a48cec4f03c16434c0bf98a4c635372a ]
+
+The shutdown is called on reboot/shutdown of the machine.
+At this point the firmware tracing cannot be used anymore but in case of
+IPC3 it is using and keeping a DMA channel active (dtrace).
+
+For Tiger Lake platforms we have a quirk in place to fix rare reboot issues
+when a DMA was active before rebooting the system.
+If the tracing is enabled this quirk will be always used and a print
+appears on the kernel log which might be misleading or not even correct.
+
+Release the fw tracing before executing the shutdown to make sure that this
+known DMA user is cleared away.
+
+Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Reviewed-by: Rander Wang <rander.wang@intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20230616100039.378150-4-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/core.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c
+index 625977a29d8a8..75a1e2c6539f2 100644
+--- a/sound/soc/sof/core.c
++++ b/sound/soc/sof/core.c
+@@ -479,8 +479,10 @@ int snd_sof_device_shutdown(struct device *dev)
+ if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE))
+ cancel_work_sync(&sdev->probe_work);
+
+- if (sdev->fw_state == SOF_FW_BOOT_COMPLETE)
++ if (sdev->fw_state == SOF_FW_BOOT_COMPLETE) {
++ sof_fw_trace_free(sdev);
+ return snd_sof_shutdown(sdev);
++ }
+
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From 996d43fd4133b656f37589b72e57322c81e2a9ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 17:25:28 -0500
+Subject: ASoC: SOF: Intel: fix SoundWire/HDaudio mutual exclusion
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit f751b99255cacd9ffe8c4bbf99767ad670cee1f7 ]
+
+The functionality described in Commit 61bef9e68dca ("ASoC: SOF: Intel: hda: enforce exclusion between HDaudio and SoundWire")
+does not seem to be properly implemented with two issues that need to
+be corrected.
+
+a) The test used is incorrect when DisplayAudio codecs are not supported.
+
+b) Conversely when only Display Audio codecs can be found, we do want
+to start the SoundWire links, if any. That will help add the relevant
+topologies and machine descriptors, and identify cases where the
+SoundWire information in ACPI needs to be modified with a quirk.
+
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Link: https://lore.kernel.org/r/20230606222529.57156-2-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/intel/hda.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
+index 1188ec51816bd..63764afdcf617 100644
+--- a/sound/soc/sof/intel/hda.c
++++ b/sound/soc/sof/intel/hda.c
+@@ -1309,12 +1309,22 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev,
+ hda_mach->mach_params.dmic_num = dmic_num;
+ pdata->tplg_filename = tplg_filename;
+
+- if (codec_num == 2) {
++ if (codec_num == 2 ||
++ (codec_num == 1 && !HDA_IDISP_CODEC(bus->codec_mask))) {
+ /*
+ * Prevent SoundWire links from starting when an external
+ * HDaudio codec is used
+ */
+ hda_mach->mach_params.link_mask = 0;
++ } else {
++ /*
++ * Allow SoundWire links to start when no external HDaudio codec
++ * was detected. This will not create a SoundWire card but
++ * will help detect if any SoundWire codec reports as ATTACHED.
++ */
++ struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
++
++ hda_mach->mach_params.link_mask = hdev->info.link_mask;
+ }
+
+ *mach = hda_mach;
+--
+2.40.1
+
--- /dev/null
+From 0c508782cd0e6367257cfec4908b502734a4d52e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 Jun 2023 12:08:10 -0500
+Subject: Bluetooth: btusb: Add MT7922 bluetooth ID for the Asus Ally
+
+From: Matthew Anderson <ruinairas1992@gmail.com>
+
+[ Upstream commit fa01eba11f0e57c767a5eab5291c7a01407a00be ]
+
+Adding the device ID from the Asus Ally gets the bluetooth working
+on the device.
+
+Signed-off-by: Matthew Anderson <ruinairas1992@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index faad19b396d50..d6f405763c56f 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -600,6 +600,9 @@ static const struct usb_device_id blacklist_table[] = {
+ { USB_DEVICE(0x0489, 0xe0d9), .driver_info = BTUSB_MEDIATEK |
+ BTUSB_WIDEBAND_SPEECH |
+ BTUSB_VALID_LE_STATES },
++ { USB_DEVICE(0x0489, 0xe0f5), .driver_info = BTUSB_MEDIATEK |
++ BTUSB_WIDEBAND_SPEECH |
++ BTUSB_VALID_LE_STATES },
+ { USB_DEVICE(0x13d3, 0x3568), .driver_info = BTUSB_MEDIATEK |
+ BTUSB_WIDEBAND_SPEECH |
+ BTUSB_VALID_LE_STATES },
+--
+2.40.1
+
--- /dev/null
+From 66def62ee6ad975eba337e350d4a71c4a0150b35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 May 2023 17:04:15 -0700
+Subject: Bluetooth: L2CAP: Fix use-after-free
+
+From: Zhengping Jiang <jiangzp@google.com>
+
+[ Upstream commit f752a0b334bb95fe9b42ecb511e0864e2768046f ]
+
+Fix potential use-after-free in l2cap_le_command_rej.
+
+Signed-off-by: Zhengping Jiang <jiangzp@google.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/l2cap_core.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 02fc9961464cf..a7899857aee5d 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -6375,9 +6375,14 @@ static inline int l2cap_le_command_rej(struct l2cap_conn *conn,
+ if (!chan)
+ goto done;
+
++ chan = l2cap_chan_hold_unless_zero(chan);
++ if (!chan)
++ goto done;
++
+ l2cap_chan_lock(chan);
+ l2cap_chan_del(chan, ECONNREFUSED);
+ l2cap_chan_unlock(chan);
++ l2cap_chan_put(chan);
+
+ done:
+ mutex_unlock(&conn->chan_lock);
+--
+2.40.1
+
--- /dev/null
+From 8d0c59d644ee82ac447be05c490dd9e5400dee2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 12:32:14 +0300
+Subject: Bluetooth: MGMT: Use correct address for memcpy()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit d1f0a9816f5fbc1316355ec1aa4ddfb9b624cca5 ]
+
+In function ‘fortify_memcpy_chk’,
+ inlined from ‘get_conn_info_complete’ at net/bluetooth/mgmt.c:7281:2:
+include/linux/fortify-string.h:592:25: error: call to
+‘__read_overflow2_field’ declared with attribute warning: detected read
+beyond size of field (2nd parameter); maybe use struct_group()?
+[-Werror=attribute-warning]
+ 592 | __read_overflow2_field(q_size_field, size);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+cc1: all warnings being treated as errors
+
+This is due to the wrong member is used for memcpy(). Use correct one.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 89c94f3e96bc3..d2e8565d0b33f 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -7277,7 +7277,7 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err)
+
+ bt_dev_dbg(hdev, "err %d", err);
+
+- memcpy(&rp.addr, &cp->addr.bdaddr, sizeof(rp.addr));
++ memcpy(&rp.addr, &cp->addr, sizeof(rp.addr));
+
+ status = mgmt_status(err);
+ if (status == MGMT_STATUS_SUCCESS) {
+--
+2.40.1
+
--- /dev/null
+From ba850e9cb9bc23dbd320aae9af13b35a25e9ad44 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Oct 2022 20:33:44 +0100
+Subject: btrfs: convert btrfs_block_group::needs_free_space to runtime flag
+
+From: David Sterba <dsterba@suse.com>
+
+[ Upstream commit 0d7764ff58b4b45c39eb03f2c74a819c1a88fa7b ]
+
+We already have flags in block group to track various status bits,
+convert needs_free_space as well and reduce size of btrfs_block_group.
+
+Reviewed-by: Anand Jain <anand.jain@oracle.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: 0657b20c5a76 ("btrfs: fix use-after-free of new block group that became unused")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/block-group.c | 2 +-
+ fs/btrfs/block-group.h | 8 ++------
+ fs/btrfs/free-space-tree.c | 10 +++++-----
+ fs/btrfs/tests/free-space-tree-tests.c | 2 +-
+ 4 files changed, 9 insertions(+), 13 deletions(-)
+
+diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
+index 9f5a971bfed42..a726b532b5277 100644
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -2543,7 +2543,7 @@ struct btrfs_block_group *btrfs_make_block_group(struct btrfs_trans_handle *tran
+ cache->global_root_id = calculate_global_root_id(fs_info, cache->start);
+
+ if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE))
+- cache->needs_free_space = 1;
++ set_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &cache->runtime_flags);
+
+ ret = btrfs_load_block_group_zone_info(cache, true);
+ if (ret) {
+diff --git a/fs/btrfs/block-group.h b/fs/btrfs/block-group.h
+index debd42aeae0f1..dcad5e959b920 100644
+--- a/fs/btrfs/block-group.h
++++ b/fs/btrfs/block-group.h
+@@ -55,6 +55,8 @@ enum btrfs_block_group_flags {
+ BLOCK_GROUP_FLAG_CHUNK_ITEM_INSERTED,
+ BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE,
+ BLOCK_GROUP_FLAG_ZONED_DATA_RELOC,
++ /* Does the block group need to be added to the free space tree? */
++ BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE,
+ };
+
+ enum btrfs_caching_type {
+@@ -204,12 +206,6 @@ struct btrfs_block_group {
+ /* Lock for free space tree operations. */
+ struct mutex free_space_lock;
+
+- /*
+- * Does the block group need to be added to the free space tree?
+- * Protected by free_space_lock.
+- */
+- int needs_free_space;
+-
+ /* Flag indicating this block group is placed on a sequential zone */
+ bool seq_zone;
+
+diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c
+index a207db9322264..6a44733a95e1c 100644
+--- a/fs/btrfs/free-space-tree.c
++++ b/fs/btrfs/free-space-tree.c
+@@ -803,7 +803,7 @@ int __remove_from_free_space_tree(struct btrfs_trans_handle *trans,
+ u32 flags;
+ int ret;
+
+- if (block_group->needs_free_space) {
++ if (test_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &block_group->runtime_flags)) {
+ ret = __add_block_group_free_space(trans, block_group, path);
+ if (ret)
+ return ret;
+@@ -996,7 +996,7 @@ int __add_to_free_space_tree(struct btrfs_trans_handle *trans,
+ u32 flags;
+ int ret;
+
+- if (block_group->needs_free_space) {
++ if (test_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &block_group->runtime_flags)) {
+ ret = __add_block_group_free_space(trans, block_group, path);
+ if (ret)
+ return ret;
+@@ -1350,7 +1350,7 @@ static int __add_block_group_free_space(struct btrfs_trans_handle *trans,
+ {
+ int ret;
+
+- block_group->needs_free_space = 0;
++ clear_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &block_group->runtime_flags);
+
+ ret = add_new_free_space_info(trans, block_group, path);
+ if (ret)
+@@ -1372,7 +1372,7 @@ int add_block_group_free_space(struct btrfs_trans_handle *trans,
+ return 0;
+
+ mutex_lock(&block_group->free_space_lock);
+- if (!block_group->needs_free_space)
++ if (!test_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &block_group->runtime_flags))
+ goto out;
+
+ path = btrfs_alloc_path();
+@@ -1405,7 +1405,7 @@ int remove_block_group_free_space(struct btrfs_trans_handle *trans,
+ if (!btrfs_fs_compat_ro(trans->fs_info, FREE_SPACE_TREE))
+ return 0;
+
+- if (block_group->needs_free_space) {
++ if (test_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &block_group->runtime_flags)) {
+ /* We never added this block group to the free space tree. */
+ return 0;
+ }
+diff --git a/fs/btrfs/tests/free-space-tree-tests.c b/fs/btrfs/tests/free-space-tree-tests.c
+index 13734ed43bfcb..766117a76d742 100644
+--- a/fs/btrfs/tests/free-space-tree-tests.c
++++ b/fs/btrfs/tests/free-space-tree-tests.c
+@@ -470,7 +470,7 @@ static int run_test(test_func_t test_func, int bitmaps, u32 sectorsize,
+ }
+ cache->bitmap_low_thresh = 0;
+ cache->bitmap_high_thresh = (u32)-1;
+- cache->needs_free_space = 1;
++ set_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &cache->runtime_flags);
+ cache->fs_info = root->fs_info;
+
+ btrfs_init_dummy_trans(&trans, root->fs_info);
+--
+2.40.1
+
--- /dev/null
+From ac6293decb3fd7be3df031c62c5617933c279125 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Oct 2022 20:33:46 +0100
+Subject: btrfs: convert btrfs_block_group::seq_zone to runtime flag
+
+From: David Sterba <dsterba@suse.com>
+
+[ Upstream commit 961f5b8bf48a463ac5fe5b13143426d79eb41817 ]
+
+In zoned mode the sequential status of zone can be also tracked in the
+runtime flags of block group.
+
+Reviewed-by: Anand Jain <anand.jain@oracle.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: 0657b20c5a76 ("btrfs: fix use-after-free of new block group that became unused")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/block-group.h | 5 ++---
+ fs/btrfs/zoned.c | 7 ++++---
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/fs/btrfs/block-group.h b/fs/btrfs/block-group.h
+index dcad5e959b920..fb4f4901350bd 100644
+--- a/fs/btrfs/block-group.h
++++ b/fs/btrfs/block-group.h
+@@ -57,6 +57,8 @@ enum btrfs_block_group_flags {
+ BLOCK_GROUP_FLAG_ZONED_DATA_RELOC,
+ /* Does the block group need to be added to the free space tree? */
+ BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE,
++ /* Indicate that the block group is placed on a sequential zone */
++ BLOCK_GROUP_FLAG_SEQUENTIAL_ZONE,
+ };
+
+ enum btrfs_caching_type {
+@@ -206,9 +208,6 @@ struct btrfs_block_group {
+ /* Lock for free space tree operations. */
+ struct mutex free_space_lock;
+
+- /* Flag indicating this block group is placed on a sequential zone */
+- bool seq_zone;
+-
+ /*
+ * Number of extents in this block group used for swap files.
+ * All accesses protected by the spinlock 'lock'.
+diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
+index 836babd23db52..9bc7ac06c5177 100644
+--- a/fs/btrfs/zoned.c
++++ b/fs/btrfs/zoned.c
+@@ -1436,7 +1436,7 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new)
+ }
+
+ if (num_sequential > 0)
+- cache->seq_zone = true;
++ set_bit(BLOCK_GROUP_FLAG_SEQUENTIAL_ZONE, &cache->runtime_flags);
+
+ if (num_conventional > 0) {
+ /* Zone capacity is always zone size in emulation */
+@@ -1658,7 +1658,7 @@ bool btrfs_use_zone_append(struct btrfs_inode *inode, u64 start)
+ if (!cache)
+ return false;
+
+- ret = cache->seq_zone;
++ ret = !!test_bit(BLOCK_GROUP_FLAG_SEQUENTIAL_ZONE, &cache->runtime_flags);
+ btrfs_put_block_group(cache);
+
+ return ret;
+@@ -2177,7 +2177,8 @@ static void btrfs_zone_finish_endio_workfn(struct work_struct *work)
+ void btrfs_schedule_zone_finish_bg(struct btrfs_block_group *bg,
+ struct extent_buffer *eb)
+ {
+- if (!bg->seq_zone || eb->start + eb->len * 2 <= bg->start + bg->zone_capacity)
++ if (!test_bit(BLOCK_GROUP_FLAG_SEQUENTIAL_ZONE, &bg->runtime_flags) ||
++ eb->start + eb->len * 2 <= bg->start + bg->zone_capacity)
+ return;
+
+ if (WARN_ON(bg->zone_finish_work.func == btrfs_zone_finish_endio_workfn)) {
+--
+2.40.1
+
--- /dev/null
+From ee22b5b44cf05ad7604b38835bb71dfd104d0dbd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Jun 2023 17:13:37 +0100
+Subject: btrfs: fix use-after-free of new block group that became unused
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 0657b20c5a76c938612f8409735a8830d257866e ]
+
+If a task creates a new block group and that block group becomes unused
+before we finish its creation, at btrfs_create_pending_block_groups(),
+then when btrfs_mark_bg_unused() is called against the block group, we
+assume that the block group is currently in the list of block groups to
+reclaim, and we move it out of the list of new block groups and into the
+list of unused block groups. This has two consequences:
+
+1) We move it out of the list of new block groups associated to the
+ current transaction. So the block group creation is not finished and
+ if we attempt to delete the bg because it's unused, we will not find
+ the block group item in the extent tree (or the new block group tree),
+ its device extent items in the device tree etc, resulting in the
+ deletion to fail due to the missing items;
+
+2) We don't increment the reference count on the block group when we
+ move it to the list of unused block groups, because we assumed the
+ block group was on the list of block groups to reclaim, and in that
+ case it already has the correct reference count. However the block
+ group was on the list of new block groups, in which case no extra
+ reference was taken because it's local to the current task. This
+ later results in doing an extra reference count decrement when
+ removing the block group from the unused list, eventually leading the
+ reference count to 0.
+
+This second case was caught when running generic/297 from fstests, which
+produced the following assertion failure and stack trace:
+
+ [589.559] assertion failed: refcount_read(&block_group->refs) == 1, in fs/btrfs/block-group.c:4299
+ [589.559] ------------[ cut here ]------------
+ [589.559] kernel BUG at fs/btrfs/block-group.c:4299!
+ [589.560] invalid opcode: 0000 [#1] PREEMPT SMP PTI
+ [589.560] CPU: 8 PID: 2819134 Comm: umount Tainted: G W 6.4.0-rc6-btrfs-next-134+ #1
+ [589.560] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014
+ [589.560] RIP: 0010:btrfs_free_block_groups+0x449/0x4a0 [btrfs]
+ [589.561] Code: 68 62 da c0 (...)
+ [589.561] RSP: 0018:ffffa55a8c3b3d98 EFLAGS: 00010246
+ [589.561] RAX: 0000000000000058 RBX: ffff8f030d7f2000 RCX: 0000000000000000
+ [589.562] RDX: 0000000000000000 RSI: ffffffff953f0878 RDI: 00000000ffffffff
+ [589.562] RBP: ffff8f030d7f2088 R08: 0000000000000000 R09: ffffa55a8c3b3c50
+ [589.562] R10: 0000000000000001 R11: 0000000000000001 R12: ffff8f05850b4c00
+ [589.562] R13: ffff8f030d7f2090 R14: ffff8f05850b4cd8 R15: dead000000000100
+ [589.563] FS: 00007f497fd2e840(0000) GS:ffff8f09dfc00000(0000) knlGS:0000000000000000
+ [589.563] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ [589.563] CR2: 00007f497ff8ec10 CR3: 0000000271472006 CR4: 0000000000370ee0
+ [589.563] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ [589.564] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+ [589.564] Call Trace:
+ [589.564] <TASK>
+ [589.565] ? __die_body+0x1b/0x60
+ [589.565] ? die+0x39/0x60
+ [589.565] ? do_trap+0xeb/0x110
+ [589.565] ? btrfs_free_block_groups+0x449/0x4a0 [btrfs]
+ [589.566] ? do_error_trap+0x6a/0x90
+ [589.566] ? btrfs_free_block_groups+0x449/0x4a0 [btrfs]
+ [589.566] ? exc_invalid_op+0x4e/0x70
+ [589.566] ? btrfs_free_block_groups+0x449/0x4a0 [btrfs]
+ [589.567] ? asm_exc_invalid_op+0x16/0x20
+ [589.567] ? btrfs_free_block_groups+0x449/0x4a0 [btrfs]
+ [589.567] ? btrfs_free_block_groups+0x449/0x4a0 [btrfs]
+ [589.567] close_ctree+0x35d/0x560 [btrfs]
+ [589.568] ? fsnotify_sb_delete+0x13e/0x1d0
+ [589.568] ? dispose_list+0x3a/0x50
+ [589.568] ? evict_inodes+0x151/0x1a0
+ [589.568] generic_shutdown_super+0x73/0x1a0
+ [589.569] kill_anon_super+0x14/0x30
+ [589.569] btrfs_kill_super+0x12/0x20 [btrfs]
+ [589.569] deactivate_locked_super+0x2e/0x70
+ [589.569] cleanup_mnt+0x104/0x160
+ [589.570] task_work_run+0x56/0x90
+ [589.570] exit_to_user_mode_prepare+0x160/0x170
+ [589.570] syscall_exit_to_user_mode+0x22/0x50
+ [589.570] ? __x64_sys_umount+0x12/0x20
+ [589.571] do_syscall_64+0x48/0x90
+ [589.571] entry_SYSCALL_64_after_hwframe+0x72/0xdc
+ [589.571] RIP: 0033:0x7f497ff0a567
+ [589.571] Code: af 98 0e (...)
+ [589.572] RSP: 002b:00007ffc98347358 EFLAGS: 00000246 ORIG_RAX: 00000000000000a6
+ [589.572] RAX: 0000000000000000 RBX: 00007f49800b8264 RCX: 00007f497ff0a567
+ [589.572] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000557f558abfa0
+ [589.573] RBP: 0000557f558a6ba0 R08: 0000000000000000 R09: 00007ffc98346100
+ [589.573] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+ [589.573] R13: 0000557f558abfa0 R14: 0000557f558a6cb0 R15: 0000557f558a6dd0
+ [589.573] </TASK>
+ [589.574] Modules linked in: dm_snapshot dm_thin_pool (...)
+ [589.576] ---[ end trace 0000000000000000 ]---
+
+Fix this by adding a runtime flag to the block group to tell that the
+block group is still in the list of new block groups, and therefore it
+should not be moved to the list of unused block groups, at
+btrfs_mark_bg_unused(), until the flag is cleared, when we finish the
+creation of the block group at btrfs_create_pending_block_groups().
+
+Fixes: a9f189716cf1 ("btrfs: move out now unused BG from the reclaim list")
+CC: stable@vger.kernel.org # 5.15+
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/block-group.c | 13 +++++++++++--
+ fs/btrfs/block-group.h | 5 +++++
+ 2 files changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
+index a726b532b5277..08017b180a10d 100644
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -1528,13 +1528,14 @@ void btrfs_mark_bg_unused(struct btrfs_block_group *bg)
+ {
+ struct btrfs_fs_info *fs_info = bg->fs_info;
+
+- trace_btrfs_add_unused_block_group(bg);
+ spin_lock(&fs_info->unused_bgs_lock);
+ if (list_empty(&bg->bg_list)) {
+ btrfs_get_block_group(bg);
++ trace_btrfs_add_unused_block_group(bg);
+ list_add_tail(&bg->bg_list, &fs_info->unused_bgs);
+- } else {
++ } else if (!test_bit(BLOCK_GROUP_FLAG_NEW, &bg->runtime_flags)) {
+ /* Pull out the block group from the reclaim_bgs list. */
++ trace_btrfs_add_unused_block_group(bg);
+ list_move_tail(&bg->bg_list, &fs_info->unused_bgs);
+ }
+ spin_unlock(&fs_info->unused_bgs_lock);
+@@ -2496,6 +2497,7 @@ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans)
+ next:
+ btrfs_delayed_refs_rsv_release(fs_info, 1);
+ list_del_init(&block_group->bg_list);
++ clear_bit(BLOCK_GROUP_FLAG_NEW, &block_group->runtime_flags);
+ }
+ btrfs_trans_release_chunk_metadata(trans);
+ }
+@@ -2535,6 +2537,13 @@ struct btrfs_block_group *btrfs_make_block_group(struct btrfs_trans_handle *tran
+ if (!cache)
+ return ERR_PTR(-ENOMEM);
+
++ /*
++ * Mark it as new before adding it to the rbtree of block groups or any
++ * list, so that no other task finds it and calls btrfs_mark_bg_unused()
++ * before the new flag is set.
++ */
++ set_bit(BLOCK_GROUP_FLAG_NEW, &cache->runtime_flags);
++
+ cache->length = size;
+ set_free_space_tree_thresholds(cache);
+ cache->used = bytes_used;
+diff --git a/fs/btrfs/block-group.h b/fs/btrfs/block-group.h
+index fb4f4901350bd..47a2dcbfee255 100644
+--- a/fs/btrfs/block-group.h
++++ b/fs/btrfs/block-group.h
+@@ -59,6 +59,11 @@ enum btrfs_block_group_flags {
+ BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE,
+ /* Indicate that the block group is placed on a sequential zone */
+ BLOCK_GROUP_FLAG_SEQUENTIAL_ZONE,
++ /*
++ * Indicate that block group is in the list of new block groups of a
++ * transaction.
++ */
++ BLOCK_GROUP_FLAG_NEW,
+ };
+
+ enum btrfs_caching_type {
+--
+2.40.1
+
--- /dev/null
+From 64f5fe86c3ce3a8882489c952f126be6810ba882 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 14:36:34 +0900
+Subject: btrfs: move out now unused BG from the reclaim list
+
+From: Naohiro Aota <naota@elisp.net>
+
+[ Upstream commit a9f189716cf15913c453299d72f69c51a9b0f86b ]
+
+An unused block group is easy to remove to free up space and should be
+reclaimed fast. Such block group can often already be a target of the
+reclaim process. As we check list_empty(&bg->bg_list), we keep it in the
+reclaim list. That block group is never reclaimed until the file system
+is filled e.g. up to 75%.
+
+Instead, we can move unused block group to the unused list and delete it
+fast.
+
+Fixes: 18bb8bbf13c1 ("btrfs: zoned: automatically reclaim zones")
+CC: stable@vger.kernel.org # 5.15+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/block-group.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
+index 3495bc775afa3..9f5a971bfed42 100644
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -1528,11 +1528,14 @@ void btrfs_mark_bg_unused(struct btrfs_block_group *bg)
+ {
+ struct btrfs_fs_info *fs_info = bg->fs_info;
+
++ trace_btrfs_add_unused_block_group(bg);
+ spin_lock(&fs_info->unused_bgs_lock);
+ if (list_empty(&bg->bg_list)) {
+ btrfs_get_block_group(bg);
+- trace_btrfs_add_unused_block_group(bg);
+ list_add_tail(&bg->bg_list, &fs_info->unused_bgs);
++ } else {
++ /* Pull out the block group from the reclaim_bgs list. */
++ list_move_tail(&bg->bg_list, &fs_info->unused_bgs);
+ }
+ spin_unlock(&fs_info->unused_bgs_lock);
+ }
+--
+2.40.1
+
--- /dev/null
+From 755aef2f45a6a450aec81f91b280fadb16e65695 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 11:44:38 +0000
+Subject: can: raw: fix lockdep issue in raw_release()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 11c9027c983e9e4b408ee5613b6504d24ebd85be ]
+
+syzbot complained about a lockdep issue [1]
+
+Since raw_bind() and raw_setsockopt() first get RTNL
+before locking the socket, we must adopt the same order in raw_release()
+
+[1]
+WARNING: possible circular locking dependency detected
+6.5.0-rc1-syzkaller-00192-g78adb4bcf99e #0 Not tainted
+------------------------------------------------------
+syz-executor.0/14110 is trying to acquire lock:
+ffff88804e4b6130 (sk_lock-AF_CAN){+.+.}-{0:0}, at: lock_sock include/net/sock.h:1708 [inline]
+ffff88804e4b6130 (sk_lock-AF_CAN){+.+.}-{0:0}, at: raw_bind+0xb1/0xab0 net/can/raw.c:435
+
+but task is already holding lock:
+ffffffff8e3df368 (rtnl_mutex){+.+.}-{3:3}, at: raw_bind+0xa7/0xab0 net/can/raw.c:434
+
+which lock already depends on the new lock.
+
+the existing dependency chain (in reverse order) is:
+
+-> #1 (rtnl_mutex){+.+.}-{3:3}:
+__mutex_lock_common kernel/locking/mutex.c:603 [inline]
+__mutex_lock+0x181/0x1340 kernel/locking/mutex.c:747
+raw_release+0x1c6/0x9b0 net/can/raw.c:391
+__sock_release+0xcd/0x290 net/socket.c:654
+sock_close+0x1c/0x20 net/socket.c:1386
+__fput+0x3fd/0xac0 fs/file_table.c:384
+task_work_run+0x14d/0x240 kernel/task_work.c:179
+resume_user_mode_work include/linux/resume_user_mode.h:49 [inline]
+exit_to_user_mode_loop kernel/entry/common.c:171 [inline]
+exit_to_user_mode_prepare+0x210/0x240 kernel/entry/common.c:204
+__syscall_exit_to_user_mode_work kernel/entry/common.c:286 [inline]
+syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:297
+do_syscall_64+0x44/0xb0 arch/x86/entry/common.c:86
+entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+-> #0 (sk_lock-AF_CAN){+.+.}-{0:0}:
+check_prev_add kernel/locking/lockdep.c:3142 [inline]
+check_prevs_add kernel/locking/lockdep.c:3261 [inline]
+validate_chain kernel/locking/lockdep.c:3876 [inline]
+__lock_acquire+0x2e3d/0x5de0 kernel/locking/lockdep.c:5144
+lock_acquire kernel/locking/lockdep.c:5761 [inline]
+lock_acquire+0x1ae/0x510 kernel/locking/lockdep.c:5726
+lock_sock_nested+0x3a/0xf0 net/core/sock.c:3492
+lock_sock include/net/sock.h:1708 [inline]
+raw_bind+0xb1/0xab0 net/can/raw.c:435
+__sys_bind+0x1ec/0x220 net/socket.c:1792
+__do_sys_bind net/socket.c:1803 [inline]
+__se_sys_bind net/socket.c:1801 [inline]
+__x64_sys_bind+0x72/0xb0 net/socket.c:1801
+do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+do_syscall_64+0x38/0xb0 arch/x86/entry/common.c:80
+entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+other info that might help us debug this:
+
+Possible unsafe locking scenario:
+
+CPU0 CPU1
+---- ----
+lock(rtnl_mutex);
+ lock(sk_lock-AF_CAN);
+ lock(rtnl_mutex);
+lock(sk_lock-AF_CAN);
+
+*** DEADLOCK ***
+
+1 lock held by syz-executor.0/14110:
+
+stack backtrace:
+CPU: 0 PID: 14110 Comm: syz-executor.0 Not tainted 6.5.0-rc1-syzkaller-00192-g78adb4bcf99e #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/03/2023
+Call Trace:
+<TASK>
+__dump_stack lib/dump_stack.c:88 [inline]
+dump_stack_lvl+0xd9/0x1b0 lib/dump_stack.c:106
+check_noncircular+0x311/0x3f0 kernel/locking/lockdep.c:2195
+check_prev_add kernel/locking/lockdep.c:3142 [inline]
+check_prevs_add kernel/locking/lockdep.c:3261 [inline]
+validate_chain kernel/locking/lockdep.c:3876 [inline]
+__lock_acquire+0x2e3d/0x5de0 kernel/locking/lockdep.c:5144
+lock_acquire kernel/locking/lockdep.c:5761 [inline]
+lock_acquire+0x1ae/0x510 kernel/locking/lockdep.c:5726
+lock_sock_nested+0x3a/0xf0 net/core/sock.c:3492
+lock_sock include/net/sock.h:1708 [inline]
+raw_bind+0xb1/0xab0 net/can/raw.c:435
+__sys_bind+0x1ec/0x220 net/socket.c:1792
+__do_sys_bind net/socket.c:1803 [inline]
+__se_sys_bind net/socket.c:1801 [inline]
+__x64_sys_bind+0x72/0xb0 net/socket.c:1801
+do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+do_syscall_64+0x38/0xb0 arch/x86/entry/common.c:80
+entry_SYSCALL_64_after_hwframe+0x63/0xcd
+RIP: 0033:0x7fd89007cb29
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 e1 20 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007fd890d2a0c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000031
+RAX: ffffffffffffffda RBX: 00007fd89019bf80 RCX: 00007fd89007cb29
+RDX: 0000000000000010 RSI: 0000000020000040 RDI: 0000000000000003
+RBP: 00007fd8900c847a R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+R13: 000000000000000b R14: 00007fd89019bf80 R15: 00007ffebf8124f8
+</TASK>
+
+Fixes: ee8b94c8510c ("can: raw: fix receiver memory leak")
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Ziyang Xuan <william.xuanziyang@huawei.com>
+Cc: Oliver Hartkopp <socketcan@hartkopp.net>
+Cc: stable@vger.kernel.org
+Cc: Marc Kleine-Budde <mkl@pengutronix.de>
+Link: https://lore.kernel.org/all/20230720114438.172434-1-edumazet@google.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/raw.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/can/raw.c b/net/can/raw.c
+index 1cd2c8748c26a..0dd3259357a35 100644
+--- a/net/can/raw.c
++++ b/net/can/raw.c
+@@ -386,9 +386,9 @@ static int raw_release(struct socket *sock)
+ list_del(&ro->notifier);
+ spin_unlock(&raw_notifier_lock);
+
++ rtnl_lock();
+ lock_sock(sk);
+
+- rtnl_lock();
+ /* remove current filters & unregister */
+ if (ro->bound) {
+ if (ro->dev)
+@@ -405,12 +405,13 @@ static int raw_release(struct socket *sock)
+ ro->dev = NULL;
+ ro->count = 0;
+ free_percpu(ro->uniq);
+- rtnl_unlock();
+
+ sock_orphan(sk);
+ sock->sk = NULL;
+
+ release_sock(sk);
++ rtnl_unlock();
++
+ sock_put(sk);
+
+ return 0;
+--
+2.40.1
+
--- /dev/null
+From efcec66b4f09662bc1994679bcc72c60aafb87c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Jul 2023 09:17:37 +0800
+Subject: can: raw: fix receiver memory leak
+
+From: Ziyang Xuan <william.xuanziyang@huawei.com>
+
+[ Upstream commit ee8b94c8510ce64afe0b87ef548d23e00915fb10 ]
+
+Got kmemleak errors with the following ltp can_filter testcase:
+
+for ((i=1; i<=100; i++))
+do
+ ./can_filter &
+ sleep 0.1
+done
+
+==============================================================
+[<00000000db4a4943>] can_rx_register+0x147/0x360 [can]
+[<00000000a289549d>] raw_setsockopt+0x5ef/0x853 [can_raw]
+[<000000006d3d9ebd>] __sys_setsockopt+0x173/0x2c0
+[<00000000407dbfec>] __x64_sys_setsockopt+0x61/0x70
+[<00000000fd468496>] do_syscall_64+0x33/0x40
+[<00000000b7e47d51>] entry_SYSCALL_64_after_hwframe+0x61/0xc6
+
+It's a bug in the concurrent scenario of unregister_netdevice_many()
+and raw_release() as following:
+
+ cpu0 cpu1
+unregister_netdevice_many(can_dev)
+ unlist_netdevice(can_dev) // dev_get_by_index() return NULL after this
+ net_set_todo(can_dev)
+ raw_release(can_socket)
+ dev = dev_get_by_index(, ro->ifindex); // dev == NULL
+ if (dev) { // receivers in dev_rcv_lists not free because dev is NULL
+ raw_disable_allfilters(, dev, );
+ dev_put(dev);
+ }
+ ...
+ ro->bound = 0;
+ ...
+
+call_netdevice_notifiers(NETDEV_UNREGISTER, )
+ raw_notify(, NETDEV_UNREGISTER, )
+ if (ro->bound) // invalid because ro->bound has been set 0
+ raw_disable_allfilters(, dev, ); // receivers in dev_rcv_lists will never be freed
+
+Add a net_device pointer member in struct raw_sock to record bound
+can_dev, and use rtnl_lock to serialize raw_socket members between
+raw_bind(), raw_release(), raw_setsockopt() and raw_notify(). Use
+ro->dev to decide whether to free receivers in dev_rcv_lists.
+
+Fixes: 8d0caedb7596 ("can: bcm/raw/isotp: use per module netdevice notifier")
+Reviewed-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Signed-off-by: Ziyang Xuan <william.xuanziyang@huawei.com>
+Link: https://lore.kernel.org/all/20230711011737.1969582-1-william.xuanziyang@huawei.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/raw.c | 57 ++++++++++++++++++++++-----------------------------
+ 1 file changed, 24 insertions(+), 33 deletions(-)
+
+diff --git a/net/can/raw.c b/net/can/raw.c
+index 4abab2c3011a3..1cd2c8748c26a 100644
+--- a/net/can/raw.c
++++ b/net/can/raw.c
+@@ -84,6 +84,7 @@ struct raw_sock {
+ struct sock sk;
+ int bound;
+ int ifindex;
++ struct net_device *dev;
+ struct list_head notifier;
+ int loopback;
+ int recv_own_msgs;
+@@ -277,7 +278,7 @@ static void raw_notify(struct raw_sock *ro, unsigned long msg,
+ if (!net_eq(dev_net(dev), sock_net(sk)))
+ return;
+
+- if (ro->ifindex != dev->ifindex)
++ if (ro->dev != dev)
+ return;
+
+ switch (msg) {
+@@ -292,6 +293,7 @@ static void raw_notify(struct raw_sock *ro, unsigned long msg,
+
+ ro->ifindex = 0;
+ ro->bound = 0;
++ ro->dev = NULL;
+ ro->count = 0;
+ release_sock(sk);
+
+@@ -337,6 +339,7 @@ static int raw_init(struct sock *sk)
+
+ ro->bound = 0;
+ ro->ifindex = 0;
++ ro->dev = NULL;
+
+ /* set default filter to single entry dfilter */
+ ro->dfilter.can_id = 0;
+@@ -385,19 +388,13 @@ static int raw_release(struct socket *sock)
+
+ lock_sock(sk);
+
++ rtnl_lock();
+ /* remove current filters & unregister */
+ if (ro->bound) {
+- if (ro->ifindex) {
+- struct net_device *dev;
+-
+- dev = dev_get_by_index(sock_net(sk), ro->ifindex);
+- if (dev) {
+- raw_disable_allfilters(dev_net(dev), dev, sk);
+- dev_put(dev);
+- }
+- } else {
++ if (ro->dev)
++ raw_disable_allfilters(dev_net(ro->dev), ro->dev, sk);
++ else
+ raw_disable_allfilters(sock_net(sk), NULL, sk);
+- }
+ }
+
+ if (ro->count > 1)
+@@ -405,8 +402,10 @@ static int raw_release(struct socket *sock)
+
+ ro->ifindex = 0;
+ ro->bound = 0;
++ ro->dev = NULL;
+ ro->count = 0;
+ free_percpu(ro->uniq);
++ rtnl_unlock();
+
+ sock_orphan(sk);
+ sock->sk = NULL;
+@@ -422,6 +421,7 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
+ struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
+ struct sock *sk = sock->sk;
+ struct raw_sock *ro = raw_sk(sk);
++ struct net_device *dev = NULL;
+ int ifindex;
+ int err = 0;
+ int notify_enetdown = 0;
+@@ -431,14 +431,13 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
+ if (addr->can_family != AF_CAN)
+ return -EINVAL;
+
++ rtnl_lock();
+ lock_sock(sk);
+
+ if (ro->bound && addr->can_ifindex == ro->ifindex)
+ goto out;
+
+ if (addr->can_ifindex) {
+- struct net_device *dev;
+-
+ dev = dev_get_by_index(sock_net(sk), addr->can_ifindex);
+ if (!dev) {
+ err = -ENODEV;
+@@ -467,26 +466,20 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
+ if (!err) {
+ if (ro->bound) {
+ /* unregister old filters */
+- if (ro->ifindex) {
+- struct net_device *dev;
+-
+- dev = dev_get_by_index(sock_net(sk),
+- ro->ifindex);
+- if (dev) {
+- raw_disable_allfilters(dev_net(dev),
+- dev, sk);
+- dev_put(dev);
+- }
+- } else {
++ if (ro->dev)
++ raw_disable_allfilters(dev_net(ro->dev),
++ ro->dev, sk);
++ else
+ raw_disable_allfilters(sock_net(sk), NULL, sk);
+- }
+ }
+ ro->ifindex = ifindex;
+ ro->bound = 1;
++ ro->dev = dev;
+ }
+
+ out:
+ release_sock(sk);
++ rtnl_unlock();
+
+ if (notify_enetdown) {
+ sk->sk_err = ENETDOWN;
+@@ -552,9 +545,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+ rtnl_lock();
+ lock_sock(sk);
+
+- if (ro->bound && ro->ifindex) {
+- dev = dev_get_by_index(sock_net(sk), ro->ifindex);
+- if (!dev) {
++ dev = ro->dev;
++ if (ro->bound && dev) {
++ if (dev->reg_state != NETREG_REGISTERED) {
+ if (count > 1)
+ kfree(filter);
+ err = -ENODEV;
+@@ -595,7 +588,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+ ro->count = count;
+
+ out_fil:
+- dev_put(dev);
+ release_sock(sk);
+ rtnl_unlock();
+
+@@ -613,9 +605,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+ rtnl_lock();
+ lock_sock(sk);
+
+- if (ro->bound && ro->ifindex) {
+- dev = dev_get_by_index(sock_net(sk), ro->ifindex);
+- if (!dev) {
++ dev = ro->dev;
++ if (ro->bound && dev) {
++ if (dev->reg_state != NETREG_REGISTERED) {
+ err = -ENODEV;
+ goto out_err;
+ }
+@@ -639,7 +631,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+ ro->err_mask = err_mask;
+
+ out_err:
+- dev_put(dev);
+ release_sock(sk);
+ rtnl_unlock();
+
+--
+2.40.1
+
--- /dev/null
+From 74395cc2c273d3844aab398d21bc334ab05dd757 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 May 2023 09:40:14 +0800
+Subject: ceph: try to dump the msgs when decoding fails
+
+From: Xiubo Li <xiubli@redhat.com>
+
+[ Upstream commit 8b0da5c549ae63ba1debd92a350f90773cb4bfe7 ]
+
+When the msgs are corrupted we need to dump them and then it will
+be easier to dig what has happened and where the issue is.
+
+Signed-off-by: Xiubo Li <xiubli@redhat.com>
+Reviewed-by: Milind Changire <mchangir@redhat.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ceph/mds_client.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
+index dcabe2783edfe..5399a9ea5b4f1 100644
+--- a/fs/ceph/mds_client.c
++++ b/fs/ceph/mds_client.c
+@@ -645,6 +645,7 @@ static int parse_reply_info(struct ceph_mds_session *s, struct ceph_msg *msg,
+ err = -EIO;
+ out_bad:
+ pr_err("mds parse_reply err %d\n", err);
++ ceph_msg_dump(msg);
+ return err;
+ }
+
+@@ -3534,6 +3535,7 @@ static void handle_forward(struct ceph_mds_client *mdsc,
+
+ bad:
+ pr_err("mdsc_handle_forward decode error err=%d\n", err);
++ ceph_msg_dump(msg);
+ }
+
+ static int __decode_session_metadata(void **p, void *end,
+@@ -5254,6 +5256,7 @@ void ceph_mdsc_handle_fsmap(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
+ bad:
+ pr_err("error decoding fsmap %d. Shutting down mount.\n", err);
+ ceph_umount_begin(mdsc->fsc->sb);
++ ceph_msg_dump(msg);
+ err_out:
+ mutex_lock(&mdsc->mutex);
+ mdsc->mdsmap_err = err;
+@@ -5322,6 +5325,7 @@ void ceph_mdsc_handle_mdsmap(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
+ bad:
+ pr_err("error decoding mdsmap %d. Shutting down mount.\n", err);
+ ceph_umount_begin(mdsc->fsc->sb);
++ ceph_msg_dump(msg);
+ return;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From e7e0d71177109e478b8cf7acc380ced733921999 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jun 2023 11:42:56 +0800
+Subject: cifs: fix session state check in reconnect to avoid use-after-free
+ issue
+
+From: Winston Wen <wentao@uniontech.com>
+
+[ Upstream commit 99f280700b4cc02d5f141b8d15f8e9fad0418f65 ]
+
+Don't collect exiting session in smb2_reconnect_server(), because it
+will be released soon.
+
+Note that the exiting session will stay in server->smb_ses_list until
+it complete the cifs_free_ipc() and logoff() and then delete itself
+from the list.
+
+Signed-off-by: Winston Wen <wentao@uniontech.com>
+Reviewed-by: Shyam Prasad N <sprasad@microsoft.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/smb2pdu.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
+index 3ca593cdda76e..ba46156e32680 100644
+--- a/fs/smb/client/smb2pdu.c
++++ b/fs/smb/client/smb2pdu.c
+@@ -3841,6 +3841,12 @@ void smb2_reconnect_server(struct work_struct *work)
+
+ spin_lock(&cifs_tcp_ses_lock);
+ list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
++ spin_lock(&ses->ses_lock);
++ if (ses->ses_status == SES_EXITING) {
++ spin_unlock(&ses->ses_lock);
++ continue;
++ }
++ spin_unlock(&ses->ses_lock);
+
+ tcon_selected = false;
+
+--
+2.40.1
+
--- /dev/null
+From dac8ee766e0113aec850058632007ff2ed7cf09b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Oct 2022 13:55:13 +0200
+Subject: cpuidle: psci: Extend information in log about OSI/PC mode
+
+From: Ulf Hansson <ulf.hansson@linaro.org>
+
+[ Upstream commit 668057b07db069daac3ca4e4978f8373db9cb71c ]
+
+It's useful to understand whether we are using OS-initiated (OSI) mode or
+Platform Coordinated (PC) mode, when initializing the CPU PM domains.
+Therefore, let's extend the print in the log after a successful probe with
+this information.
+
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Acked-by: Sudeep Holla <sudeep.holla@arm.com
+Acked-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: 12acb348fa45 ("cpuidle: psci: Move enabling OSI mode after power domains creation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpuidle/cpuidle-psci-domain.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c
+index fe06644725203..1fca250d5dece 100644
+--- a/drivers/cpuidle/cpuidle-psci-domain.c
++++ b/drivers/cpuidle/cpuidle-psci-domain.c
+@@ -182,7 +182,8 @@ static int psci_cpuidle_domain_probe(struct platform_device *pdev)
+ if (ret)
+ goto remove_pd;
+
+- pr_info("Initialized CPU PM domain topology\n");
++ pr_info("Initialized CPU PM domain topology using %s mode\n",
++ use_osi ? "OSI" : "PC");
+ return 0;
+
+ put_node:
+--
+2.40.1
+
--- /dev/null
+From 8c7aaf091c8cdfd437717b2f6369543603d8c6e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Jul 2023 14:25:54 +0530
+Subject: cpuidle: psci: Move enabling OSI mode after power domains creation
+
+From: Maulik Shah <quic_mkshah@quicinc.com>
+
+[ Upstream commit 12acb348fa4528a4203edf1cce7a3be2c9af2279 ]
+
+A switch from OSI to PC mode is only possible if all CPUs other than the
+calling one are OFF, either through a call to CPU_OFF or not yet booted.
+
+Currently OSI mode is enabled before power domains are created. In cases
+where CPUidle states are not using hierarchical CPU topology the bail out
+path tries to switch back to PC mode which gets denied by firmware since
+other CPUs are online at this point and creates inconsistent state as
+firmware is in OSI mode and Linux in PC mode.
+
+This change moves enabling OSI mode after power domains are created,
+this would makes sure that hierarchical CPU topology is used before
+switching firmware to OSI mode.
+
+Cc: stable@vger.kernel.org
+Fixes: 70c179b49870 ("cpuidle: psci: Allow PM domain to be initialized even if no OSI mode")
+Signed-off-by: Maulik Shah <quic_mkshah@quicinc.com>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpuidle/cpuidle-psci-domain.c | 39 +++++++++------------------
+ 1 file changed, 13 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c
+index 1fca250d5dece..f5d4359555d77 100644
+--- a/drivers/cpuidle/cpuidle-psci-domain.c
++++ b/drivers/cpuidle/cpuidle-psci-domain.c
+@@ -117,20 +117,6 @@ static void psci_pd_remove(void)
+ }
+ }
+
+-static bool psci_pd_try_set_osi_mode(void)
+-{
+- int ret;
+-
+- if (!psci_has_osi_support())
+- return false;
+-
+- ret = psci_set_osi_mode(true);
+- if (ret)
+- return false;
+-
+- return true;
+-}
+-
+ static void psci_cpuidle_domain_sync_state(struct device *dev)
+ {
+ /*
+@@ -149,15 +135,12 @@ static int psci_cpuidle_domain_probe(struct platform_device *pdev)
+ {
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *node;
+- bool use_osi;
++ bool use_osi = psci_has_osi_support();
+ int ret = 0, pd_count = 0;
+
+ if (!np)
+ return -ENODEV;
+
+- /* If OSI mode is supported, let's try to enable it. */
+- use_osi = psci_pd_try_set_osi_mode();
+-
+ /*
+ * Parse child nodes for the "#power-domain-cells" property and
+ * initialize a genpd/genpd-of-provider pair when it's found.
+@@ -167,33 +150,37 @@ static int psci_cpuidle_domain_probe(struct platform_device *pdev)
+ continue;
+
+ ret = psci_pd_init(node, use_osi);
+- if (ret)
+- goto put_node;
++ if (ret) {
++ of_node_put(node);
++ goto exit;
++ }
+
+ pd_count++;
+ }
+
+ /* Bail out if not using the hierarchical CPU topology. */
+ if (!pd_count)
+- goto no_pd;
++ return 0;
+
+ /* Link genpd masters/subdomains to model the CPU topology. */
+ ret = dt_idle_pd_init_topology(np);
+ if (ret)
+ goto remove_pd;
+
++ /* let's try to enable OSI. */
++ ret = psci_set_osi_mode(use_osi);
++ if (ret)
++ goto remove_pd;
++
+ pr_info("Initialized CPU PM domain topology using %s mode\n",
+ use_osi ? "OSI" : "PC");
+ return 0;
+
+-put_node:
+- of_node_put(node);
+ remove_pd:
++ dt_idle_pd_remove_topology(np);
+ psci_pd_remove();
++exit:
+ pr_err("failed to create CPU PM domains ret=%d\n", ret);
+-no_pd:
+- if (use_osi)
+- psci_set_osi_mode(false);
+ return ret;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From a5710a956eb91e6a3c0626af8b961cc518576b81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jun 2023 12:47:37 +0000
+Subject: dma-remap: use kvmalloc_array/kvfree for larger dma memory remap
+
+From: gaoxu <gaoxu2@hihonor.com>
+
+[ Upstream commit 51ff97d54f02b4444dfc42e380ac4c058e12d5dd ]
+
+If dma_direct_alloc() alloc memory in size of 64MB, the inner function
+dma_common_contiguous_remap() will allocate 128KB memory by invoking
+the function kmalloc_array(). and the kmalloc_array seems to fail to try to
+allocate 128KB mem.
+
+Call trace:
+[14977.928623] qcrosvm: page allocation failure: order:5, mode:0x40cc0
+[14977.928638] dump_backtrace.cfi_jt+0x0/0x8
+[14977.928647] dump_stack_lvl+0x80/0xb8
+[14977.928652] warn_alloc+0x164/0x200
+[14977.928657] __alloc_pages_slowpath+0x9f0/0xb4c
+[14977.928660] __alloc_pages+0x21c/0x39c
+[14977.928662] kmalloc_order+0x48/0x108
+[14977.928666] kmalloc_order_trace+0x34/0x154
+[14977.928668] __kmalloc+0x548/0x7e4
+[14977.928673] dma_direct_alloc+0x11c/0x4f8
+[14977.928678] dma_alloc_attrs+0xf4/0x138
+[14977.928680] gh_vm_ioctl_set_fw_name+0x3c4/0x610 [gunyah]
+[14977.928698] gh_vm_ioctl+0x90/0x14c [gunyah]
+[14977.928705] __arm64_sys_ioctl+0x184/0x210
+
+work around by doing kvmalloc_array instead.
+
+Signed-off-by: Gao Xu <gaoxu2@hihonor.com>
+Reviewed-by: Suren Baghdasaryan <surenb@google.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/dma/remap.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/dma/remap.c b/kernel/dma/remap.c
+index b4526668072e7..27596f3b4aef3 100644
+--- a/kernel/dma/remap.c
++++ b/kernel/dma/remap.c
+@@ -43,13 +43,13 @@ void *dma_common_contiguous_remap(struct page *page, size_t size,
+ void *vaddr;
+ int i;
+
+- pages = kmalloc_array(count, sizeof(struct page *), GFP_KERNEL);
++ pages = kvmalloc_array(count, sizeof(struct page *), GFP_KERNEL);
+ if (!pages)
+ return NULL;
+ for (i = 0; i < count; i++)
+ pages[i] = nth_page(page, i);
+ vaddr = vmap(pages, count, VM_DMA_COHERENT, prot);
+- kfree(pages);
++ kvfree(pages);
+
+ return vaddr;
+ }
+--
+2.40.1
+
--- /dev/null
+From 3b801b0d043bc5aba283f2ba4c89e5fe920ca4af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 May 2023 15:25:01 -0400
+Subject: drm/amd/display: Apply 60us prefetch for DCFCLK <= 300Mhz
+
+From: Alvin Lee <alvin.lee2@amd.com>
+
+[ Upstream commit 7e60ab4eb3e4ba2adac46d737fdbbc5732bebd58 ]
+
+[Description]
+- Previously we wanted to apply extra 60us of prefetch for min DCFCLK
+ (200Mhz), but DCFCLK can be calculated to be 201Mhz which underflows
+ also without the extra prefetch
+- Instead, apply the the extra 60us prefetch for any DCFCLK freq <=
+ 300Mhz
+
+Reviewed-by: Nevenko Stupar <nevenko.stupar@amd.com>
+Reviewed-by: Jun Lei <jun.lei@amd.com>
+Acked-by: Tom Chung <chiahsuan.chung@amd.com>
+Signed-off-by: Alvin Lee <alvin.lee2@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c | 4 ++--
+ .../gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+index 2bb768413c92a..19f55657272e4 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+@@ -808,7 +808,7 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
+ v->SwathHeightC[k],
+ TWait,
+ (v->DRAMSpeedPerState[mode_lib->vba.VoltageLevel] <= MEM_STROBE_FREQ_MHZ ||
+- v->DCFCLKPerState[mode_lib->vba.VoltageLevel] <= MIN_DCFCLK_FREQ_MHZ) ?
++ v->DCFCLKPerState[mode_lib->vba.VoltageLevel] <= DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ) ?
+ mode_lib->vba.ip.min_prefetch_in_strobe_us : 0,
+ /* Output */
+ &v->DSTXAfterScaler[k],
+@@ -3289,7 +3289,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ v->swath_width_chroma_ub_this_state[k],
+ v->SwathHeightYThisState[k],
+ v->SwathHeightCThisState[k], v->TWait,
+- (v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ || v->DCFCLKState[i][j] <= MIN_DCFCLK_FREQ_MHZ) ?
++ (v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ || v->DCFCLKState[i][j] <= DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ) ?
+ mode_lib->vba.ip.min_prefetch_in_strobe_us : 0,
+
+ /* Output */
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h
+index e92eee2c664d0..a475775bc3894 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.h
+@@ -52,7 +52,7 @@
+ #define BPP_BLENDED_PIPE 0xffffffff
+
+ #define MEM_STROBE_FREQ_MHZ 1600
+-#define MIN_DCFCLK_FREQ_MHZ 200
++#define DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ 300
+ #define MEM_STROBE_MAX_DELIVERY_TIME_US 60.0
+
+ struct display_mode_lib;
+--
+2.40.1
+
--- /dev/null
+From 25e1b173b187bdff63d138af0e2ee6742161fa1a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 May 2023 13:02:01 -0400
+Subject: drm/amd/display: Enable dcn314 DPP RCO
+
+From: Daniel Miess <daniel.miess@amd.com>
+
+[ Upstream commit 17fbdbda9cc87ff5a013898de506212d25323ed7 ]
+
+[Why and How]
+Add back debug bits enabling RCO for dcn314 as underflow
+associated with this change has been resolved
+
+Acked-by: Stylon Wang <stylon.wang@amd.com>
+Signed-off-by: Daniel Miess <daniel.miess@amd.com>
+Reviewed-by: Jun Lei <jun.lei@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/amd/display/dc/dcn314/dcn314_resource.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+index b7782433ce6ba..012f6369dae22 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+@@ -920,6 +920,22 @@ static const struct dc_debug_options debug_defaults_drv = {
+ .afmt = true,
+ }
+ },
++
++ .root_clock_optimization = {
++ .bits = {
++ .dpp = true,
++ .dsc = false,
++ .hdmistream = false,
++ .hdmichar = false,
++ .dpstream = false,
++ .symclk32_se = false,
++ .symclk32_le = false,
++ .symclk_fe = false,
++ .physymclk = false,
++ .dpiasymclk = false,
++ }
++ },
++
+ .seamless_boot_odm_combine = true
+ };
+
+--
+2.40.1
+
--- /dev/null
+From a8283881e4d2ab59c503e5ce57f744581c8f7fa0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Mar 2023 10:45:24 -0400
+Subject: drm/amd/display: fix access hdcp_workqueue assert
+
+From: Hersen Wu <hersenxs.wu@amd.com>
+
+[ Upstream commit cdff36a0217aadf5cbc167893ad1c0da869619cb ]
+
+[Why] hdcp are enabled for asics from raven. for old asics
+which hdcp are not enabled, hdcp_workqueue are null. some
+access to hdcp work queue are not guarded with pointer check.
+
+[How] add hdcp_workqueue pointer check before access workqueue.
+
+Reviewed-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Hersen Wu <hersenxs.wu@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 ++++++
+ .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 16 ++++++++++------
+ 2 files changed, 16 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index aa0ea28a86f02..249b269e2cc53 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -8372,6 +8372,9 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+ struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
+ struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
+
++ if (!adev->dm.hdcp_workqueue)
++ continue;
++
+ pr_debug("[HDCP_DM] -------------- i : %x ----------\n", i);
+
+ if (!connector)
+@@ -8420,6 +8423,9 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+ struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
+ struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
+
++ if (!adev->dm.hdcp_workqueue)
++ continue;
++
+ new_crtc_state = NULL;
+ old_crtc_state = NULL;
+
+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 9884dd78c652c..a9ddff774a978 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
+@@ -379,13 +379,17 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
+ if (aconnector->dc_sink && connector->state) {
+ struct drm_device *dev = connector->dev;
+ struct amdgpu_device *adev = drm_to_adev(dev);
+- struct hdcp_workqueue *hdcp_work = adev->dm.hdcp_workqueue;
+- struct hdcp_workqueue *hdcp_w = &hdcp_work[aconnector->dc_link->link_index];
+
+- connector->state->hdcp_content_type =
+- hdcp_w->hdcp_content_type[connector->index];
+- connector->state->content_protection =
+- hdcp_w->content_protection[connector->index];
++ if (adev->dm.hdcp_workqueue) {
++ struct hdcp_workqueue *hdcp_work = adev->dm.hdcp_workqueue;
++ struct hdcp_workqueue *hdcp_w =
++ &hdcp_work[aconnector->dc_link->link_index];
++
++ connector->state->hdcp_content_type =
++ hdcp_w->hdcp_content_type[connector->index];
++ connector->state->content_protection =
++ hdcp_w->content_protection[connector->index];
++ }
+ }
+ #endif
+
+--
+2.40.1
+
--- /dev/null
+From 3bae8906784530006600201049b2e8eff6daddbd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2022 14:20:56 -0500
+Subject: drm/amd/display: phase3 mst hdcp for multiple displays
+
+From: hersen wu <hersenxs.wu@amd.com>
+
+[ Upstream commit e8fd3eeb5e8711af39b00642da06474e52f4780c ]
+
+[Why]
+multiple display hdcp are enabled within event_property_validate,
+event_property_update by looping all displays on mst hub. when
+one of display on mst hub in unplugged or disabled, hdcp are
+disabled for all displays on mst hub within hdcp_reset_display
+by looping all displays of mst link. for displays still active,
+their encryption status are off. kernel driver will not run hdcp
+authentication again. therefore, hdcp are not enabled automatically.
+
+[How]
+within is_content_protection_different, check drm_crtc_state changes
+of all displays on mst hub, if need, triger hdcp_update_display to
+re-run hdcp authentication.
+
+Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Signed-off-by: hersen wu <hersenxs.wu@amd.com>
+Reviewed-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: cdff36a0217a ("drm/amd/display: fix access hdcp_workqueue assert")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 183 ++++++++++++++----
+ 1 file changed, 141 insertions(+), 42 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index bdc6f90b3adb5..aa0ea28a86f02 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -7397,27 +7397,55 @@ is_scaling_state_different(const struct dm_connector_state *dm_state,
+ }
+
+ #ifdef CONFIG_DRM_AMD_DC_HDCP
+-static bool is_content_protection_different(struct drm_connector_state *state,
+- const struct drm_connector_state *old_state,
+- const struct drm_connector *connector, struct hdcp_workqueue *hdcp_w)
++static bool is_content_protection_different(struct drm_crtc_state *new_crtc_state,
++ struct drm_crtc_state *old_crtc_state,
++ struct drm_connector_state *new_conn_state,
++ struct drm_connector_state *old_conn_state,
++ const struct drm_connector *connector,
++ struct hdcp_workqueue *hdcp_w)
+ {
+ struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
+ struct dm_connector_state *dm_con_state = to_dm_connector_state(connector->state);
+
+- /* Handle: Type0/1 change */
+- if (old_state->hdcp_content_type != state->hdcp_content_type &&
+- state->content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
+- state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
++ pr_debug("[HDCP_DM] connector->index: %x connect_status: %x dpms: %x\n",
++ connector->index, connector->status, connector->dpms);
++ pr_debug("[HDCP_DM] state protection old: %x new: %x\n",
++ old_conn_state->content_protection, new_conn_state->content_protection);
++
++ if (old_crtc_state)
++ pr_debug("[HDCP_DM] old crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n",
++ old_crtc_state->enable,
++ old_crtc_state->active,
++ old_crtc_state->mode_changed,
++ old_crtc_state->active_changed,
++ old_crtc_state->connectors_changed);
++
++ if (new_crtc_state)
++ pr_debug("[HDCP_DM] NEW crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n",
++ new_crtc_state->enable,
++ new_crtc_state->active,
++ new_crtc_state->mode_changed,
++ new_crtc_state->active_changed,
++ new_crtc_state->connectors_changed);
++
++ /* hdcp content type change */
++ if (old_conn_state->hdcp_content_type != new_conn_state->hdcp_content_type &&
++ new_conn_state->content_protection != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
++ new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
++ pr_debug("[HDCP_DM] Type0/1 change %s :true\n", __func__);
+ return true;
+ }
+
+- /* CP is being re enabled, ignore this
+- *
+- * Handles: ENABLED -> DESIRED
+- */
+- if (old_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+- state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
+- state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED;
++ /* CP is being re enabled, ignore this */
++ if (old_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
++ new_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
++ if (new_crtc_state && new_crtc_state->mode_changed) {
++ new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
++ pr_debug("[HDCP_DM] ENABLED->DESIRED & mode_changed %s :true\n", __func__);
++ return true;
++ };
++ new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_ENABLED;
++ pr_debug("[HDCP_DM] ENABLED -> DESIRED %s :false\n", __func__);
+ return false;
+ }
+
+@@ -7425,9 +7453,9 @@ static bool is_content_protection_different(struct drm_connector_state *state,
+ *
+ * Handles: UNDESIRED -> ENABLED
+ */
+- if (old_state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
+- state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+- state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
++ if (old_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
++ new_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED)
++ new_conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+
+ /* Stream removed and re-enabled
+ *
+@@ -7437,10 +7465,12 @@ static bool is_content_protection_different(struct drm_connector_state *state,
+ *
+ * Handles: DESIRED -> DESIRED (Special case)
+ */
+- if (!(old_state->crtc && old_state->crtc->enabled) &&
+- state->crtc && state->crtc->enabled &&
++ if (!(old_conn_state->crtc && old_conn_state->crtc->enabled) &&
++ new_conn_state->crtc && new_conn_state->crtc->enabled &&
+ connector->state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
+ dm_con_state->update_hdcp = false;
++ pr_debug("[HDCP_DM] DESIRED->DESIRED (Stream removed and re-enabled) %s :true\n",
++ __func__);
+ return true;
+ }
+
+@@ -7452,35 +7482,42 @@ static bool is_content_protection_different(struct drm_connector_state *state,
+ *
+ * Handles: DESIRED -> DESIRED (Special case)
+ */
+- if (dm_con_state->update_hdcp && state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+- connector->dpms == DRM_MODE_DPMS_ON && aconnector->dc_sink != NULL) {
++ if (dm_con_state->update_hdcp &&
++ new_conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
++ connector->dpms == DRM_MODE_DPMS_ON && aconnector->dc_sink != NULL) {
+ dm_con_state->update_hdcp = false;
++ pr_debug("[HDCP_DM] DESIRED->DESIRED (Hot-plug, headless s3, dpms) %s :true\n",
++ __func__);
+ return true;
+ }
+
+- /*
+- * Handles: UNDESIRED -> UNDESIRED
+- * DESIRED -> DESIRED
+- * ENABLED -> ENABLED
+- */
+- if (old_state->content_protection == state->content_protection)
++ if (old_conn_state->content_protection == new_conn_state->content_protection) {
++ if (new_conn_state->content_protection >= DRM_MODE_CONTENT_PROTECTION_DESIRED) {
++ if (new_crtc_state && new_crtc_state->mode_changed) {
++ pr_debug("[HDCP_DM] DESIRED->DESIRED or ENABLE->ENABLE mode_change %s :true\n",
++ __func__);
++ return true;
++ };
++ pr_debug("[HDCP_DM] DESIRED->DESIRED & ENABLE->ENABLE %s :false\n",
++ __func__);
++ return false;
++ };
++
++ pr_debug("[HDCP_DM] UNDESIRED->UNDESIRED %s :false\n", __func__);
+ return false;
++ }
+
+- /*
+- * Handles: UNDESIRED -> DESIRED
+- * DESIRED -> UNDESIRED
+- * ENABLED -> UNDESIRED
+- */
+- if (state->content_protection != DRM_MODE_CONTENT_PROTECTION_ENABLED)
++ if (new_conn_state->content_protection != DRM_MODE_CONTENT_PROTECTION_ENABLED) {
++ pr_debug("[HDCP_DM] UNDESIRED->DESIRED or DESIRED->UNDESIRED or ENABLED->UNDESIRED %s :true\n",
++ __func__);
+ return true;
++ }
+
+- /*
+- * Handles: DESIRED -> ENABLED
+- */
++ pr_debug("[HDCP_DM] DESIRED->ENABLED %s :false\n", __func__);
+ return false;
+ }
+-
+ #endif
++
+ static void remove_stream(struct amdgpu_device *adev,
+ struct amdgpu_crtc *acrtc,
+ struct dc_stream_state *stream)
+@@ -8330,15 +8367,66 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+ }
+ }
+ #ifdef CONFIG_DRM_AMD_DC_HDCP
++ for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
++ struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
++ struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
++ struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
++
++ pr_debug("[HDCP_DM] -------------- i : %x ----------\n", i);
++
++ if (!connector)
++ continue;
++
++ pr_debug("[HDCP_DM] connector->index: %x connect_status: %x dpms: %x\n",
++ connector->index, connector->status, connector->dpms);
++ pr_debug("[HDCP_DM] state protection old: %x new: %x\n",
++ old_con_state->content_protection, new_con_state->content_protection);
++
++ if (aconnector->dc_sink) {
++ if (aconnector->dc_sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
++ aconnector->dc_sink->sink_signal != SIGNAL_TYPE_NONE) {
++ pr_debug("[HDCP_DM] pipe_ctx dispname=%s\n",
++ aconnector->dc_sink->edid_caps.display_name);
++ }
++ }
++
++ new_crtc_state = NULL;
++ old_crtc_state = NULL;
++
++ if (acrtc) {
++ new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base);
++ old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base);
++ }
++
++ if (old_crtc_state)
++ pr_debug("old crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n",
++ old_crtc_state->enable,
++ old_crtc_state->active,
++ old_crtc_state->mode_changed,
++ old_crtc_state->active_changed,
++ old_crtc_state->connectors_changed);
++
++ if (new_crtc_state)
++ pr_debug("NEW crtc en: %x a: %x m: %x a-chg: %x c-chg: %x\n",
++ new_crtc_state->enable,
++ new_crtc_state->active,
++ new_crtc_state->mode_changed,
++ new_crtc_state->active_changed,
++ new_crtc_state->connectors_changed);
++ }
++
+ for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
+ struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
+ struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
+ struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
+
+ new_crtc_state = NULL;
++ old_crtc_state = NULL;
+
+- if (acrtc)
++ if (acrtc) {
+ new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base);
++ old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base);
++ }
+
+ dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
+
+@@ -8350,7 +8438,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+ continue;
+ }
+
+- if (is_content_protection_different(new_con_state, old_con_state, connector, adev->dm.hdcp_workqueue)) {
++ if (is_content_protection_different(new_crtc_state, old_crtc_state, new_con_state,
++ old_con_state, connector, adev->dm.hdcp_workqueue)) {
+ /* when display is unplugged from mst hub, connctor will
+ * be destroyed within dm_dp_mst_connector_destroy. connector
+ * hdcp perperties, like type, undesired, desired, enabled,
+@@ -8360,6 +8449,11 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+ * will be retrieved from hdcp_work within dm_dp_mst_get_modes
+ */
+
++ bool enable_encryption = false;
++
++ if (new_con_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED)
++ enable_encryption = true;
++
+ if (aconnector->dc_link && aconnector->dc_sink &&
+ aconnector->dc_link->type == dc_connection_mst_branch) {
+ struct hdcp_workqueue *hdcp_work = adev->dm.hdcp_workqueue;
+@@ -8372,11 +8466,16 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+ new_con_state->content_protection;
+ }
+
++ if (new_crtc_state && new_crtc_state->mode_changed &&
++ new_con_state->content_protection >= DRM_MODE_CONTENT_PROTECTION_DESIRED)
++ enable_encryption = true;
++
++ DRM_INFO("[HDCP_DM] hdcp_update_display enable_encryption = %x\n", enable_encryption);
++
+ hdcp_update_display(
+ adev->dm.hdcp_workqueue, aconnector->dc_link->link_index, aconnector,
+- new_con_state->hdcp_content_type,
+- new_con_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED);
+- }
++ new_con_state->hdcp_content_type, enable_encryption);
++ }
+ }
+ #endif
+
+--
+2.40.1
+
--- /dev/null
+From d31337125357cf64d061f493dcedd78ef7d55ccb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2022 10:39:55 -0500
+Subject: drm/amd/display: save restore hdcp state when display is unplugged
+ from mst hub
+
+From: hersen wu <hersenxs.wu@amd.com>
+
+[ Upstream commit 82986fd631fa04bcedaefe11a6b3767601cbe84f ]
+
+[Why]
+connector hdcp properties are lost after display is
+unplgged from mst hub. connector is destroyed with
+dm_dp_mst_connector_destroy. when display is plugged
+back, hdcp is not desired and it wouldnt be enabled.
+
+[How]
+save hdcp properties into hdcp_work within
+amdgpu_dm_atomic_commit_tail. If the same display is
+plugged back with same display index, its hdcp
+properties will be retrieved from hdcp_work within
+dm_dp_mst_get_modes.
+
+Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Signed-off-by: hersen wu <hersenxs.wu@amd.com>
+Reviewed-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: cdff36a0217a ("drm/amd/display: fix access hdcp_workqueue assert")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 24 ++++++++++++++++-
+ .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.h | 14 ++++++++++
+ .../display/amdgpu_dm/amdgpu_dm_mst_types.c | 26 +++++++++++++++++++
+ 3 files changed, 63 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 9f718b98da1f7..bdc6f90b3adb5 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -8350,11 +8350,33 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+ continue;
+ }
+
+- if (is_content_protection_different(new_con_state, old_con_state, connector, adev->dm.hdcp_workqueue))
++ if (is_content_protection_different(new_con_state, old_con_state, connector, adev->dm.hdcp_workqueue)) {
++ /* when display is unplugged from mst hub, connctor will
++ * be destroyed within dm_dp_mst_connector_destroy. connector
++ * hdcp perperties, like type, undesired, desired, enabled,
++ * will be lost. So, save hdcp properties into hdcp_work within
++ * amdgpu_dm_atomic_commit_tail. if the same display is
++ * plugged back with same display index, its hdcp properties
++ * will be retrieved from hdcp_work within dm_dp_mst_get_modes
++ */
++
++ if (aconnector->dc_link && aconnector->dc_sink &&
++ aconnector->dc_link->type == dc_connection_mst_branch) {
++ struct hdcp_workqueue *hdcp_work = adev->dm.hdcp_workqueue;
++ struct hdcp_workqueue *hdcp_w =
++ &hdcp_work[aconnector->dc_link->link_index];
++
++ hdcp_w->hdcp_content_type[connector->index] =
++ new_con_state->hdcp_content_type;
++ hdcp_w->content_protection[connector->index] =
++ new_con_state->content_protection;
++ }
++
+ hdcp_update_display(
+ adev->dm.hdcp_workqueue, aconnector->dc_link->link_index, aconnector,
+ new_con_state->hdcp_content_type,
+ new_con_state->content_protection == DRM_MODE_CONTENT_PROTECTION_DESIRED);
++ }
+ }
+ #endif
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h
+index 09294ff122fea..bbbf7d0eff82f 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.h
+@@ -52,6 +52,20 @@ struct hdcp_workqueue {
+ struct mod_hdcp_link link;
+
+ enum mod_hdcp_encryption_status encryption_status;
++
++ /* when display is unplugged from mst hub, connctor will be
++ * destroyed within dm_dp_mst_connector_destroy. connector
++ * hdcp perperties, like type, undesired, desired, enabled,
++ * will be lost. So, save hdcp properties into hdcp_work within
++ * amdgpu_dm_atomic_commit_tail. if the same display is
++ * plugged back with same display index, its hdcp properties
++ * will be retrieved from hdcp_work within dm_dp_mst_get_modes
++ */
++ /* un-desired, desired, enabled */
++ unsigned int content_protection[AMDGPU_DM_MAX_DISPLAY_INDEX];
++ /* hdcp1.x, hdcp2.x */
++ unsigned int hdcp_content_type[AMDGPU_DM_MAX_DISPLAY_INDEX];
++
+ uint8_t max_link;
+
+ uint8_t *srm;
+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 d07e1053b36b3..9884dd78c652c 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
+@@ -32,6 +32,10 @@
+ #include "amdgpu_dm.h"
+ #include "amdgpu_dm_mst_types.h"
+
++#ifdef CONFIG_DRM_AMD_DC_HDCP
++#include "amdgpu_dm_hdcp.h"
++#endif
++
+ #include "dc.h"
+ #include "dm_helpers.h"
+
+@@ -363,6 +367,28 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
+ /* dc_link_add_remote_sink returns a new reference */
+ aconnector->dc_sink = dc_sink;
+
++ /* when display is unplugged from mst hub, connctor will be
++ * destroyed within dm_dp_mst_connector_destroy. connector
++ * hdcp perperties, like type, undesired, desired, enabled,
++ * will be lost. So, save hdcp properties into hdcp_work within
++ * amdgpu_dm_atomic_commit_tail. if the same display is
++ * plugged back with same display index, its hdcp properties
++ * will be retrieved from hdcp_work within dm_dp_mst_get_modes
++ */
++#ifdef CONFIG_DRM_AMD_DC_HDCP
++ if (aconnector->dc_sink && connector->state) {
++ struct drm_device *dev = connector->dev;
++ struct amdgpu_device *adev = drm_to_adev(dev);
++ struct hdcp_workqueue *hdcp_work = adev->dm.hdcp_workqueue;
++ struct hdcp_workqueue *hdcp_w = &hdcp_work[aconnector->dc_link->link_index];
++
++ connector->state->hdcp_content_type =
++ hdcp_w->hdcp_content_type[connector->index];
++ connector->state->content_protection =
++ hdcp_w->content_protection[connector->index];
++ }
++#endif
++
+ if (aconnector->dc_sink) {
+ amdgpu_dm_update_freesync_caps(
+ connector, aconnector->edid);
+--
+2.40.1
+
--- /dev/null
+From 4ffa7971cff4a49ebc87a522a926de641e0f8b6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Apr 2023 11:23:50 -0400
+Subject: drm/amd/display: Skip DPP DTO update if root clock is gated
+
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+
+[ Upstream commit 30f90f3c1c2c63c2fa44f61233737d27b72637c2 ]
+
+[Why]
+Hardware implements root clock gating by utilizing the DPP DTO registers
+with a special case of DTO enabled, phase = 0, modulo = 1. This
+conflicts with our policy to always update the DPPDTO for cases where
+it's expected to be disabled.
+
+The pipes unexpectedly enter a higher power state than expected because
+of this programming flow.
+
+[How]
+Guard the upper layers of HWSS against this hardware quirk with
+programming the register with an internal state flag in DCCG.
+
+While technically acting as global state for the DCCG, HWSS shouldn't be
+expected to understand the hardware quirk for having DTO disabled
+causing more power than DTO enabled with this specific setting.
+
+This also prevents sequencing errors from occuring in the future if
+we have to program DPP DTO in multiple locations.
+
+Acked-by: Stylon Wang <stylon.wang@amd.com>
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Reviewed-by: Jun Lei <jun.lei@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c | 8 ++++++++
+ drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c | 5 +++++
+ drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h | 1 +
+ 3 files changed, 14 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c
+index 7d2b982506fd7..cef32a1f91cdc 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c
+@@ -47,6 +47,14 @@ void dccg31_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk)
+ {
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
++ if (dccg->dpp_clock_gated[dpp_inst]) {
++ /*
++ * Do not update the DPPCLK DTO if the clock is stopped.
++ * It is treated the same as if the pipe itself were in PG.
++ */
++ return;
++ }
++
+ if (dccg->ref_dppclk && req_dppclk) {
+ int ref_dppclk = dccg->ref_dppclk;
+ int modulo, phase;
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c
+index 85ea3334355c2..97c6a79dfba66 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c
+@@ -296,6 +296,9 @@ static void dccg314_dpp_root_clock_control(
+ {
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
++ if (dccg->dpp_clock_gated[dpp_inst] == clock_on)
++ return;
++
+ if (clock_on) {
+ /* turn off the DTO and leave phase/modulo at max */
+ REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_ENABLE[dpp_inst], 0);
+@@ -309,6 +312,8 @@ static void dccg314_dpp_root_clock_control(
+ DPPCLK0_DTO_PHASE, 0,
+ DPPCLK0_DTO_MODULO, 1);
+ }
++
++ dccg->dpp_clock_gated[dpp_inst] = !clock_on;
+ }
+
+ static const struct dccg_funcs dccg314_funcs = {
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
+index ad6acd1b34e1d..9651cccb084a3 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
+@@ -68,6 +68,7 @@ struct dccg {
+ const struct dccg_funcs *funcs;
+ int pipe_dppclk_khz[MAX_PIPES];
+ int ref_dppclk;
++ bool dpp_clock_gated[MAX_PIPES];
+ //int dtbclk_khz[MAX_PIPES];/* TODO needs to be removed */
+ //int audio_dtbclk_khz;/* TODO needs to be removed */
+ //int ref_dtbclk_khz;/* TODO needs to be removed */
+--
+2.40.1
+
--- /dev/null
+From e6f1af51f5a3287a2bfdf23615ffab439b094663 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Apr 2023 13:21:45 +0800
+Subject: drm/amdgpu: fix calltrace warning in amddrm_buddy_fini
+
+From: Longlong Yao <Longlong.Yao@amd.com>
+
+[ Upstream commit 01382501509871d0799bab6bd412c228486af5bf ]
+
+The following call trace is observed when removing the amdgpu driver, which
+is caused by that BOs allocated for psp are not freed until removing.
+
+[61811.450562] RIP: 0010:amddrm_buddy_fini.cold+0x29/0x47 [amddrm_buddy]
+[61811.450577] Call Trace:
+[61811.450577] <TASK>
+[61811.450579] amdgpu_vram_mgr_fini+0x135/0x1c0 [amdgpu]
+[61811.450728] amdgpu_ttm_fini+0x207/0x290 [amdgpu]
+[61811.450870] amdgpu_bo_fini+0x27/0xa0 [amdgpu]
+[61811.451012] gmc_v9_0_sw_fini+0x4a/0x60 [amdgpu]
+[61811.451166] amdgpu_device_fini_sw+0x117/0x520 [amdgpu]
+[61811.451306] amdgpu_driver_release_kms+0x16/0x30 [amdgpu]
+[61811.451447] devm_drm_dev_init_release+0x4d/0x80 [drm]
+[61811.451466] devm_action_release+0x15/0x20
+[61811.451469] release_nodes+0x40/0xb0
+[61811.451471] devres_release_all+0x9b/0xd0
+[61811.451473] __device_release_driver+0x1bb/0x2a0
+[61811.451476] driver_detach+0xf3/0x140
+[61811.451479] bus_remove_driver+0x6c/0xf0
+[61811.451481] driver_unregister+0x31/0x60
+[61811.451483] pci_unregister_driver+0x40/0x90
+[61811.451486] amdgpu_exit+0x15/0x447 [amdgpu]
+
+For smu v13_0_2, if the GPU supports xgmi, refer to
+
+commit f5c7e7797060 ("drm/amdgpu: Adjust removal control flow for smu v13_0_2"),
+
+it will run gpu recover in AMDGPU_RESET_FOR_DEVICE_REMOVE mode when removing,
+which makes all devices in hive list have hw reset but no resume except the
+basic ip blocks, then other ip blocks will not call .hw_fini according to
+ip_block.status.hw.
+
+Since psp_free_shared_bufs just includes some software operations, so move
+it to psp_sw_fini.
+
+Reviewed-by: Guchun Chen <guchun.chen@amd.com>
+Reviewed-by: Feifei Xu <Feifei.Xu@amd.com>
+Signed-off-by: Longlong Yao <Longlong.Yao@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 | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+index eecbd8eeb1f5a..8764ff7ed97e0 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+@@ -514,6 +514,8 @@ static int psp_sw_fini(void *handle)
+ kfree(cmd);
+ cmd = NULL;
+
++ psp_free_shared_bufs(psp);
++
+ if (psp->km_ring.ring_mem)
+ amdgpu_bo_free_kernel(&adev->firmware.rbuf,
+ &psp->km_ring.ring_mem_mc_addr,
+@@ -2673,8 +2675,6 @@ static int psp_hw_fini(void *handle)
+
+ psp_ring_destroy(psp, PSP_RING_TYPE__KM);
+
+- psp_free_shared_bufs(psp);
+-
+ return 0;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From fabbb4f1999594036fb93eb33f19cf209eb0cf31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Apr 2023 20:22:33 +0800
+Subject: drm/amdgpu: Fix integer overflow in amdgpu_cs_pass1
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: hackyzh002 <hackyzh002@gmail.com>
+
+[ Upstream commit 87c2213e85bd81e4a9a4d0880c256568794ae388 ]
+
+The type of size is unsigned int, if size is 0x40000000, there will
+be an integer overflow, size will be zero after size *= sizeof(uint32_t),
+will cause uninitialized memory to be referenced later.
+
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: hackyzh002 <hackyzh002@gmail.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+index fdb53d4394f30..6d3d01c5f0a28 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+@@ -185,7 +185,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
+ uint64_t *chunk_array_user;
+ uint64_t *chunk_array;
+ uint32_t uf_offset = 0;
+- unsigned int size;
++ size_t size;
+ int ret;
+ int i;
+
+--
+2.40.1
+
--- /dev/null
+From b59246c134ef7e7472343948e447d14f90573779 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Apr 2023 14:20:38 +0800
+Subject: drm/amdgpu: fix memory leak in mes self test
+
+From: Jack Xiao <Jack.Xiao@amd.com>
+
+[ Upstream commit 31d7c3a4fc3d312a0646990767647925d5bde540 ]
+
+The fences associated with mes queue have to be freed
+up during amdgpu_ring_fini.
+
+Signed-off-by: Jack Xiao <Jack.Xiao@amd.com>
+Reviewed-by: Hawking Zhang <Hawking.Zhang@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_ring.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+index d3558c34d406c..296b2d5976af7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+@@ -361,6 +361,8 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring)
+ amdgpu_bo_free_kernel(&ring->ring_obj,
+ &ring->gpu_addr,
+ (void **)&ring->ring);
++ } else {
++ kfree(ring->fence_drv.fences);
+ }
+
+ dma_fence_put(ring->vmid_wait);
+--
+2.40.1
+
--- /dev/null
+From d2500db32fb4e42c6e05eb14dd0b0485e0ea4540 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Jun 2023 18:10:47 -0700
+Subject: drm/amdgpu: Fix potential fence use-after-free v2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: shanzhulig <shanzhulig@gmail.com>
+
+[ Upstream commit 2e54154b9f27262efd0cb4f903cc7d5ad1fe9628 ]
+
+fence Decrements the reference count before exiting.
+Avoid Race Vulnerabilities for fence use-after-free.
+
+v2 (chk): actually fix the use after free and not just move it.
+
+Signed-off-by: shanzhulig <shanzhulig@gmail.com>
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@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_cs.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+index 6d3d01c5f0a28..02a112d00d413 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+@@ -1607,15 +1607,15 @@ static int amdgpu_cs_wait_all_fences(struct amdgpu_device *adev,
+ continue;
+
+ r = dma_fence_wait_timeout(fence, true, timeout);
++ if (r > 0 && fence->error)
++ r = fence->error;
++
+ dma_fence_put(fence);
+ if (r < 0)
+ return r;
+
+ if (r == 0)
+ break;
+-
+- if (fence->error)
+- return fence->error;
+ }
+
+ memset(wait, 0, sizeof(*wait));
+--
+2.40.1
+
--- /dev/null
+From 5f2f9b5a5a93eac7bef9f7e2304d1adac629dcc9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 May 2023 20:14:15 +0800
+Subject: drm/amdgpu: install stub fence into potential unused fence pointers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lang Yu <Lang.Yu@amd.com>
+
+[ Upstream commit 187916e6ed9d0c3b3abc27429f7a5f8c936bd1f0 ]
+
+When using cpu to update page tables, vm update fences are unused.
+Install stub fence into these fence pointers instead of NULL
+to avoid NULL dereference when calling dma_fence_wait() on them.
+
+Suggested-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Lang Yu <Lang.Yu@amd.com>
+Reviewed-by: Christian König <christian.koenig@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_vm.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+index ec938a1a50621..4c661e024e13d 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+@@ -1352,6 +1352,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
+ amdgpu_vm_bo_base_init(&bo_va->base, vm, bo);
+
+ bo_va->ref_count = 1;
++ bo_va->last_pt_update = dma_fence_get_stub();
+ INIT_LIST_HEAD(&bo_va->valids);
+ INIT_LIST_HEAD(&bo_va->invalids);
+
+@@ -2073,7 +2074,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
+ vm->update_funcs = &amdgpu_vm_cpu_funcs;
+ else
+ vm->update_funcs = &amdgpu_vm_sdma_funcs;
+- vm->last_update = NULL;
++
++ vm->last_update = dma_fence_get_stub();
+ vm->last_unlocked = dma_fence_get_stub();
+ vm->last_tlb_flush = dma_fence_get_stub();
+
+@@ -2198,7 +2200,7 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm)
+ goto unreserve_bo;
+
+ dma_fence_put(vm->last_update);
+- vm->last_update = NULL;
++ vm->last_update = dma_fence_get_stub();
+ vm->is_compute_context = true;
+
+ /* Free the shadow bo for compute VM */
+--
+2.40.1
+
--- /dev/null
+From f85b45b6fff3222b196abf7022fec2059ec7f4c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 May 2023 09:48:17 +0200
+Subject: drm: rcar-du: remove R-Car H3 ES1.* workarounds
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit 2da4b728f994a1f9189a8066b0be90b615768764 ]
+
+R-Car H3 ES1.* was only available to an internal development group and
+needed a lot of quirks and workarounds. These become a maintenance
+burden now, so our development group decided to remove upstream support
+for this SoC and prevent booting it. Public users only have ES2 onwards.
+
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 37 ++------------------
+ drivers/gpu/drm/rcar-du/rcar_du_drv.c | 48 --------------------------
+ drivers/gpu/drm/rcar-du/rcar_du_drv.h | 2 --
+ drivers/gpu/drm/rcar-du/rcar_du_regs.h | 3 +-
+ 4 files changed, 4 insertions(+), 86 deletions(-)
+
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+index b7dd59fe119e6..9edb5edb2bad9 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+@@ -223,20 +223,6 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
+ * DU channels that have a display PLL can't use the internal
+ * system clock, and have no internal clock divider.
+ */
+-
+- /*
+- * The H3 ES1.x exhibits dot clock duty cycle stability issues.
+- * We can work around them by configuring the DPLL to twice the
+- * desired frequency, coupled with a /2 post-divider. Restrict
+- * the workaround to H3 ES1.x as ES2.0 and all other SoCs have
+- * no post-divider when a display PLL is present (as shown by
+- * the workaround breaking HDMI output on M3-W during testing).
+- */
+- if (rcdu->info->quirks & RCAR_DU_QUIRK_H3_ES1_PCLK_STABILITY) {
+- target *= 2;
+- div = 1;
+- }
+-
+ extclk = clk_get_rate(rcrtc->extclock);
+ rcar_du_dpll_divider(rcrtc, &dpll, extclk, target);
+
+@@ -245,30 +231,13 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
+ | DPLLCR_N(dpll.n) | DPLLCR_M(dpll.m)
+ | DPLLCR_STBY;
+
+- if (rcrtc->index == 1) {
++ if (rcrtc->index == 1)
+ dpllcr |= DPLLCR_PLCS1
+ | DPLLCR_INCS_DOTCLKIN1;
+- } else {
+- dpllcr |= DPLLCR_PLCS0_PLL
++ else
++ dpllcr |= DPLLCR_PLCS0
+ | DPLLCR_INCS_DOTCLKIN0;
+
+- /*
+- * On ES2.x we have a single mux controlled via bit 21,
+- * which selects between DCLKIN source (bit 21 = 0) and
+- * a PLL source (bit 21 = 1), where the PLL is always
+- * PLL1.
+- *
+- * On ES1.x we have an additional mux, controlled
+- * via bit 20, for choosing between PLL0 (bit 20 = 0)
+- * and PLL1 (bit 20 = 1). We always want to use PLL1,
+- * so on ES1.x, in addition to setting bit 21, we need
+- * to set the bit 20.
+- */
+-
+- if (rcdu->info->quirks & RCAR_DU_QUIRK_H3_ES1_PLL)
+- dpllcr |= DPLLCR_PLCS0_H3ES1X_PLL1;
+- }
+-
+ rcar_du_group_write(rcrtc->group, DPLLCR, dpllcr);
+
+ escr = ESCR_DCLKSEL_DCLKIN | div;
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+index 6381578c4db58..bd7003d6e0753 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+@@ -16,7 +16,6 @@
+ #include <linux/platform_device.h>
+ #include <linux/pm.h>
+ #include <linux/slab.h>
+-#include <linux/sys_soc.h>
+ #include <linux/wait.h>
+
+ #include <drm/drm_atomic_helper.h>
+@@ -387,43 +386,6 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
+ .dpll_mask = BIT(2) | BIT(1),
+ };
+
+-static const struct rcar_du_device_info rcar_du_r8a7795_es1_info = {
+- .gen = 3,
+- .features = RCAR_DU_FEATURE_CRTC_IRQ
+- | RCAR_DU_FEATURE_CRTC_CLOCK
+- | RCAR_DU_FEATURE_VSP1_SOURCE
+- | RCAR_DU_FEATURE_INTERLACED
+- | RCAR_DU_FEATURE_TVM_SYNC,
+- .quirks = RCAR_DU_QUIRK_H3_ES1_PCLK_STABILITY
+- | RCAR_DU_QUIRK_H3_ES1_PLL,
+- .channels_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0),
+- .routes = {
+- /*
+- * R8A7795 has one RGB output, two HDMI outputs and one
+- * LVDS output.
+- */
+- [RCAR_DU_OUTPUT_DPAD0] = {
+- .possible_crtcs = BIT(3),
+- .port = 0,
+- },
+- [RCAR_DU_OUTPUT_HDMI0] = {
+- .possible_crtcs = BIT(1),
+- .port = 1,
+- },
+- [RCAR_DU_OUTPUT_HDMI1] = {
+- .possible_crtcs = BIT(2),
+- .port = 2,
+- },
+- [RCAR_DU_OUTPUT_LVDS0] = {
+- .possible_crtcs = BIT(0),
+- .port = 3,
+- },
+- },
+- .num_lvds = 1,
+- .num_rpf = 5,
+- .dpll_mask = BIT(2) | BIT(1),
+-};
+-
+ static const struct rcar_du_device_info rcar_du_r8a7796_info = {
+ .gen = 3,
+ .features = RCAR_DU_FEATURE_CRTC_IRQ
+@@ -592,11 +554,6 @@ static const struct of_device_id rcar_du_of_table[] = {
+
+ MODULE_DEVICE_TABLE(of, rcar_du_of_table);
+
+-static const struct soc_device_attribute rcar_du_soc_table[] = {
+- { .soc_id = "r8a7795", .revision = "ES1.*", .data = &rcar_du_r8a7795_es1_info },
+- { /* sentinel */ }
+-};
+-
+ const char *rcar_du_output_name(enum rcar_du_output output)
+ {
+ static const char * const names[] = {
+@@ -688,7 +645,6 @@ static void rcar_du_shutdown(struct platform_device *pdev)
+
+ static int rcar_du_probe(struct platform_device *pdev)
+ {
+- const struct soc_device_attribute *soc_attr;
+ struct rcar_du_device *rcdu;
+ unsigned int mask;
+ int ret;
+@@ -706,10 +662,6 @@ static int rcar_du_probe(struct platform_device *pdev)
+
+ rcdu->info = of_device_get_match_data(rcdu->dev);
+
+- soc_attr = soc_device_match(rcar_du_soc_table);
+- if (soc_attr)
+- rcdu->info = soc_attr->data;
+-
+ platform_set_drvdata(pdev, rcdu);
+
+ /* I/O resources */
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+index acc3673fefe18..5cfa2bb7ad93d 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+@@ -34,8 +34,6 @@ struct rcar_du_device;
+ #define RCAR_DU_FEATURE_NO_BLENDING BIT(5) /* PnMR.SPIM does not have ALP nor EOR bits */
+
+ #define RCAR_DU_QUIRK_ALIGN_128B BIT(0) /* Align pitches to 128 bytes */
+-#define RCAR_DU_QUIRK_H3_ES1_PCLK_STABILITY BIT(1) /* H3 ES1 has pclk stability issue */
+-#define RCAR_DU_QUIRK_H3_ES1_PLL BIT(2) /* H3 ES1 PLL setup differs from non-ES1 */
+
+ enum rcar_du_output {
+ RCAR_DU_OUTPUT_DPAD0,
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_regs.h b/drivers/gpu/drm/rcar-du/rcar_du_regs.h
+index 789ae9285108e..288eff12b2b1a 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_regs.h
++++ b/drivers/gpu/drm/rcar-du/rcar_du_regs.h
+@@ -283,8 +283,7 @@
+ #define DPLLCR 0x20044
+ #define DPLLCR_CODE (0x95 << 24)
+ #define DPLLCR_PLCS1 (1 << 23)
+-#define DPLLCR_PLCS0_PLL (1 << 21)
+-#define DPLLCR_PLCS0_H3ES1X_PLL1 (1 << 20)
++#define DPLLCR_PLCS0 (1 << 21)
+ #define DPLLCR_CLKE (1 << 18)
+ #define DPLLCR_FDPLL(n) ((n) << 12)
+ #define DPLLCR_N(n) ((n) << 5)
+--
+2.40.1
+
--- /dev/null
+From ccf1f461e5d2a7950620f07017b8e72d84805cec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 May 2023 14:38:18 +0200
+Subject: drm/stm: ltdc: fix late dereference check
+
+From: Raphael Gallais-Pou <raphael.gallais-pou@foss.st.com>
+
+[ Upstream commit 898a9e3f56db9860ab091d4bf41b6caa99aafc3d ]
+
+In ltdc_crtc_set_crc_source(), struct drm_crtc was dereferenced in a
+container_of() before the pointer check. This could cause a kernel panic.
+
+Fix this smatch warning:
+drivers/gpu/drm/stm/ltdc.c:1124 ltdc_crtc_set_crc_source() warn: variable dereferenced before check 'crtc' (see line 1119)
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/lkml/202212241802.zeLFZCXB-lkp@intel.com/
+Reported-by: Dan Carpenter <error27@gmail.com>
+Closes: https://lore.kernel.org/lkml/202212241802.zeLFZCXB-lkp@intel.com/
+Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou@foss.st.com>
+Acked-by: Philippe Cornu <philippe.cornu@foss.st.com>
+Signed-off-by: Philippe Cornu <philippe.cornu@foss.st.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230515123818.93971-1-raphael.gallais-pou@foss.st.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/stm/ltdc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
+index 03c6becda795c..b8be4c1db4235 100644
+--- a/drivers/gpu/drm/stm/ltdc.c
++++ b/drivers/gpu/drm/stm/ltdc.c
+@@ -1145,7 +1145,7 @@ static void ltdc_crtc_disable_vblank(struct drm_crtc *crtc)
+
+ static int ltdc_crtc_set_crc_source(struct drm_crtc *crtc, const char *source)
+ {
+- struct ltdc_device *ldev = crtc_to_ltdc(crtc);
++ struct ltdc_device *ldev;
+ int ret;
+
+ DRM_DEBUG_DRIVER("\n");
+@@ -1153,6 +1153,8 @@ static int ltdc_crtc_set_crc_source(struct drm_crtc *crtc, const char *source)
+ if (!crtc)
+ return -ENODEV;
+
++ ldev = crtc_to_ltdc(crtc);
++
+ if (source && strcmp(source, "auto") == 0) {
+ ldev->crc_active = true;
+ ret = regmap_set_bits(ldev->regmap, LTDC_GCR, GCR_CRCEN);
+--
+2.40.1
+
--- /dev/null
+From 1d05bd8a9820bca9ebf1d6035e032deb0ae257a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Dec 2022 17:05:06 +0100
+Subject: fbdev/hyperv-fb: Do not set struct fb_info.apertures
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit 81d2393485f0990cf6566b0c9e0697c199f68ae5 ]
+
+Generic fbdev drivers use the apertures field in struct fb_info to
+control ownership of the framebuffer memory and graphics device. Do
+not set the values in hyperv-fb.
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Reviewed-by: Michael Kelley <mikelley@microsoft.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20221219160516.23436-9-tzimmermann@suse.de
+Stable-dep-of: 5ae3716cfdcd ("video/aperture: Only remove sysfb on the default vga pci device")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/hyperv_fb.c | 17 ++++++-----------
+ 1 file changed, 6 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
+index 4ff25dfc865d9..d3d643cf7506c 100644
+--- a/drivers/video/fbdev/hyperv_fb.c
++++ b/drivers/video/fbdev/hyperv_fb.c
+@@ -995,13 +995,10 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
+ struct pci_dev *pdev = NULL;
+ void __iomem *fb_virt;
+ int gen2vm = efi_enabled(EFI_BOOT);
++ resource_size_t base, size;
+ phys_addr_t paddr;
+ int ret;
+
+- info->apertures = alloc_apertures(1);
+- if (!info->apertures)
+- return -ENOMEM;
+-
+ if (!gen2vm) {
+ pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT,
+ PCI_DEVICE_ID_HYPERV_VIDEO, NULL);
+@@ -1010,8 +1007,8 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
+ return -ENODEV;
+ }
+
+- info->apertures->ranges[0].base = pci_resource_start(pdev, 0);
+- info->apertures->ranges[0].size = pci_resource_len(pdev, 0);
++ base = pci_resource_start(pdev, 0);
++ size = pci_resource_len(pdev, 0);
+
+ /*
+ * For Gen 1 VM, we can directly use the contiguous memory
+@@ -1034,8 +1031,8 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
+ }
+ pr_info("Unable to allocate enough contiguous physical memory on Gen 1 VM. Using MMIO instead.\n");
+ } else {
+- info->apertures->ranges[0].base = screen_info.lfb_base;
+- info->apertures->ranges[0].size = screen_info.lfb_size;
++ base = screen_info.lfb_base;
++ size = screen_info.lfb_size;
+ }
+
+ /*
+@@ -1077,9 +1074,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
+ info->screen_size = dio_fb_size;
+
+ getmem_done:
+- aperture_remove_conflicting_devices(info->apertures->ranges[0].base,
+- info->apertures->ranges[0].size,
+- false, KBUILD_MODNAME);
++ aperture_remove_conflicting_devices(base, size, false, KBUILD_MODNAME);
+
+ if (gen2vm) {
+ /* framebuffer is reallocated, clear screen_info to avoid misuse from kexec */
+--
+2.40.1
+
--- /dev/null
+From 77bdf3797f242a5e124ec46b3e9cefaf72a2576e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Jun 2023 13:39:35 +0800
+Subject: firewire: net: fix use after free in fwnet_finish_incoming_packet()
+
+From: Zhang Shurong <zhang_shurong@foxmail.com>
+
+[ Upstream commit 3ff256751a2853e1ffaa36958ff933ccc98c6cb5 ]
+
+The netif_rx() function frees the skb so we can't dereference it to
+save the skb->len.
+
+Signed-off-by: Zhang Shurong <zhang_shurong@foxmail.com>
+Link: https://lore.kernel.org/r/tencent_3B3D24B66ED66A6BB73CC0E63C6A14E45109@qq.com
+Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firewire/net.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
+index af22be84034bb..a53eacebca339 100644
+--- a/drivers/firewire/net.c
++++ b/drivers/firewire/net.c
+@@ -479,7 +479,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
+ struct sk_buff *skb, u16 source_node_id,
+ bool is_broadcast, u16 ether_type)
+ {
+- int status;
++ int status, len;
+
+ switch (ether_type) {
+ case ETH_P_ARP:
+@@ -533,13 +533,15 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
+ }
+ skb->protocol = protocol;
+ }
++
++ len = skb->len;
+ status = netif_rx(skb);
+ if (status == NET_RX_DROP) {
+ net->stats.rx_errors++;
+ net->stats.rx_dropped++;
+ } else {
+ net->stats.rx_packets++;
+- net->stats.rx_bytes += skb->len;
++ net->stats.rx_bytes += len;
+ }
+
+ return 0;
+--
+2.40.1
+
--- /dev/null
+From 6d5fd3f6e13993264df2bdf236d90709e520d83d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Mar 2023 10:56:55 +0800
+Subject: fs/ntfs3: Enhance sanity check while generating attr_list
+
+From: Edward Lo <loyuantsung@gmail.com>
+
+[ Upstream commit fdec309c7672cbee4dc0229ee4cbb33c948a1bdd ]
+
+ni_create_attr_list uses WARN_ON to catch error cases while generating
+attribute list, which only prints out stack trace and may not be enough.
+This repalces them with more proper error handling flow.
+
+[ 59.666332] BUG: kernel NULL pointer dereference, address: 000000000000000e
+[ 59.673268] #PF: supervisor read access in kernel mode
+[ 59.678354] #PF: error_code(0x0000) - not-present page
+[ 59.682831] PGD 8000000005ff1067 P4D 8000000005ff1067 PUD 7dee067 PMD 0
+[ 59.688556] Oops: 0000 [#1] PREEMPT SMP KASAN PTI
+[ 59.692642] CPU: 0 PID: 198 Comm: poc Tainted: G B W 6.2.0-rc1+ #4
+[ 59.698868] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
+[ 59.708795] RIP: 0010:ni_create_attr_list+0x505/0x860
+[ 59.713657] Code: 7e 10 e8 5e d0 d0 ff 45 0f b7 76 10 48 8d 7b 16 e8 00 d1 d0 ff 66 44 89 73 16 4d 8d 75 0e 4c 89 f7 e8 3f d0 d0 ff 4c 8d8
+[ 59.731559] RSP: 0018:ffff88800a56f1e0 EFLAGS: 00010282
+[ 59.735691] RAX: 0000000000000001 RBX: ffff88800b7b5088 RCX: ffffffffb83079fe
+[ 59.741792] RDX: 0000000000000001 RSI: 0000000000000008 RDI: ffffffffbb7f9fc0
+[ 59.748423] RBP: ffff88800a56f3a8 R08: ffff88800b7b50a0 R09: fffffbfff76ff3f9
+[ 59.754654] R10: ffffffffbb7f9fc7 R11: fffffbfff76ff3f8 R12: ffff88800b756180
+[ 59.761552] R13: 0000000000000000 R14: 000000000000000e R15: 0000000000000050
+[ 59.768323] FS: 00007feaa8c96440(0000) GS:ffff88806d400000(0000) knlGS:0000000000000000
+[ 59.776027] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 59.781395] CR2: 00007f3a2e0b1000 CR3: 000000000a5bc000 CR4: 00000000000006f0
+[ 59.787607] Call Trace:
+[ 59.790271] <TASK>
+[ 59.792488] ? __pfx_ni_create_attr_list+0x10/0x10
+[ 59.797235] ? kernel_text_address+0xd3/0xe0
+[ 59.800856] ? unwind_get_return_address+0x3e/0x60
+[ 59.805101] ? __kasan_check_write+0x18/0x20
+[ 59.809296] ? preempt_count_sub+0x1c/0xd0
+[ 59.813421] ni_ins_attr_ext+0x52c/0x5c0
+[ 59.817034] ? __pfx_ni_ins_attr_ext+0x10/0x10
+[ 59.821926] ? __vfs_setxattr+0x121/0x170
+[ 59.825718] ? __vfs_setxattr_noperm+0x97/0x300
+[ 59.829562] ? __vfs_setxattr_locked+0x145/0x170
+[ 59.833987] ? vfs_setxattr+0x137/0x2a0
+[ 59.836732] ? do_setxattr+0xce/0x150
+[ 59.839807] ? setxattr+0x126/0x140
+[ 59.842353] ? path_setxattr+0x164/0x180
+[ 59.845275] ? __x64_sys_setxattr+0x71/0x90
+[ 59.848838] ? do_syscall_64+0x3f/0x90
+[ 59.851898] ? entry_SYSCALL_64_after_hwframe+0x72/0xdc
+[ 59.857046] ? stack_depot_save+0x17/0x20
+[ 59.860299] ni_insert_attr+0x1ba/0x420
+[ 59.863104] ? __pfx_ni_insert_attr+0x10/0x10
+[ 59.867069] ? preempt_count_sub+0x1c/0xd0
+[ 59.869897] ? _raw_spin_unlock_irqrestore+0x2b/0x50
+[ 59.874088] ? __create_object+0x3ae/0x5d0
+[ 59.877865] ni_insert_resident+0xc4/0x1c0
+[ 59.881430] ? __pfx_ni_insert_resident+0x10/0x10
+[ 59.886355] ? kasan_save_alloc_info+0x1f/0x30
+[ 59.891117] ? __kasan_kmalloc+0x8b/0xa0
+[ 59.894383] ntfs_set_ea+0x90d/0xbf0
+[ 59.897703] ? __pfx_ntfs_set_ea+0x10/0x10
+[ 59.901011] ? kernel_text_address+0xd3/0xe0
+[ 59.905308] ? __kernel_text_address+0x16/0x50
+[ 59.909811] ? unwind_get_return_address+0x3e/0x60
+[ 59.914898] ? __pfx_stack_trace_consume_entry+0x10/0x10
+[ 59.920250] ? arch_stack_walk+0xa2/0x100
+[ 59.924560] ? filter_irq_stacks+0x27/0x80
+[ 59.928722] ntfs_setxattr+0x405/0x440
+[ 59.932512] ? __pfx_ntfs_setxattr+0x10/0x10
+[ 59.936634] ? kvmalloc_node+0x2d/0x120
+[ 59.940378] ? kasan_save_stack+0x41/0x60
+[ 59.943870] ? kasan_save_stack+0x2a/0x60
+[ 59.947719] ? kasan_set_track+0x29/0x40
+[ 59.951417] ? kasan_save_alloc_info+0x1f/0x30
+[ 59.955733] ? __kasan_kmalloc+0x8b/0xa0
+[ 59.959598] ? __kmalloc_node+0x68/0x150
+[ 59.963163] ? kvmalloc_node+0x2d/0x120
+[ 59.966490] ? vmemdup_user+0x2b/0xa0
+[ 59.969060] __vfs_setxattr+0x121/0x170
+[ 59.972456] ? __pfx___vfs_setxattr+0x10/0x10
+[ 59.976008] __vfs_setxattr_noperm+0x97/0x300
+[ 59.981562] __vfs_setxattr_locked+0x145/0x170
+[ 59.986100] vfs_setxattr+0x137/0x2a0
+[ 59.989964] ? __pfx_vfs_setxattr+0x10/0x10
+[ 59.993616] ? __kasan_check_write+0x18/0x20
+[ 59.997425] do_setxattr+0xce/0x150
+[ 60.000304] setxattr+0x126/0x140
+[ 60.002967] ? __pfx_setxattr+0x10/0x10
+[ 60.006471] ? __virt_addr_valid+0xcb/0x140
+[ 60.010461] ? __call_rcu_common.constprop.0+0x1c7/0x330
+[ 60.016037] ? debug_smp_processor_id+0x1b/0x30
+[ 60.021008] ? kasan_quarantine_put+0x5b/0x190
+[ 60.025545] ? putname+0x84/0xa0
+[ 60.027910] ? __kasan_slab_free+0x11e/0x1b0
+[ 60.031483] ? putname+0x84/0xa0
+[ 60.033986] ? preempt_count_sub+0x1c/0xd0
+[ 60.036876] ? __mnt_want_write+0xae/0x100
+[ 60.040738] ? mnt_want_write+0x8f/0x150
+[ 60.044317] path_setxattr+0x164/0x180
+[ 60.048096] ? __pfx_path_setxattr+0x10/0x10
+[ 60.052096] ? strncpy_from_user+0x175/0x1c0
+[ 60.056482] ? debug_smp_processor_id+0x1b/0x30
+[ 60.059848] ? fpregs_assert_state_consistent+0x6b/0x80
+[ 60.064557] __x64_sys_setxattr+0x71/0x90
+[ 60.068892] do_syscall_64+0x3f/0x90
+[ 60.072868] entry_SYSCALL_64_after_hwframe+0x72/0xdc
+[ 60.077523] RIP: 0033:0x7feaa86e4469
+[ 60.080915] Code: 00 f3 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 088
+[ 60.097353] RSP: 002b:00007ffdbd8311e8 EFLAGS: 00000286 ORIG_RAX: 00000000000000bc
+[ 60.103386] RAX: ffffffffffffffda RBX: 9461c5e290baac00 RCX: 00007feaa86e4469
+[ 60.110322] RDX: 00007ffdbd831fe0 RSI: 00007ffdbd831305 RDI: 00007ffdbd831263
+[ 60.116808] RBP: 00007ffdbd836180 R08: 0000000000000001 R09: 00007ffdbd836268
+[ 60.123879] R10: 000000000000007d R11: 0000000000000286 R12: 0000000000400500
+[ 60.130540] R13: 00007ffdbd836260 R14: 0000000000000000 R15: 0000000000000000
+[ 60.136553] </TASK>
+[ 60.138818] Modules linked in:
+[ 60.141839] CR2: 000000000000000e
+[ 60.144831] ---[ end trace 0000000000000000 ]---
+[ 60.149058] RIP: 0010:ni_create_attr_list+0x505/0x860
+[ 60.153975] Code: 7e 10 e8 5e d0 d0 ff 45 0f b7 76 10 48 8d 7b 16 e8 00 d1 d0 ff 66 44 89 73 16 4d 8d 75 0e 4c 89 f7 e8 3f d0 d0 ff 4c 8d8
+[ 60.172443] RSP: 0018:ffff88800a56f1e0 EFLAGS: 00010282
+[ 60.176246] RAX: 0000000000000001 RBX: ffff88800b7b5088 RCX: ffffffffb83079fe
+[ 60.182752] RDX: 0000000000000001 RSI: 0000000000000008 RDI: ffffffffbb7f9fc0
+[ 60.189949] RBP: ffff88800a56f3a8 R08: ffff88800b7b50a0 R09: fffffbfff76ff3f9
+[ 60.196950] R10: ffffffffbb7f9fc7 R11: fffffbfff76ff3f8 R12: ffff88800b756180
+[ 60.203671] R13: 0000000000000000 R14: 000000000000000e R15: 0000000000000050
+[ 60.209595] FS: 00007feaa8c96440(0000) GS:ffff88806d400000(0000) knlGS:0000000000000000
+[ 60.216299] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 60.222276] CR2: 00007f3a2e0b1000 CR3: 000000000a5bc000 CR4: 00000000000006f0
+
+Signed-off-by: Edward Lo <loyuantsung@gmail.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/frecord.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
+index b1b476fb7229b..dda13e1f1b330 100644
+--- a/fs/ntfs3/frecord.c
++++ b/fs/ntfs3/frecord.c
+@@ -874,6 +874,7 @@ int ni_create_attr_list(struct ntfs_inode *ni)
+ if (err)
+ goto out1;
+
++ err = -EINVAL;
+ /* Call mi_remove_attr() in reverse order to keep pointers 'arr_move' valid. */
+ while (to_free > 0) {
+ struct ATTRIB *b = arr_move[--nb];
+@@ -882,7 +883,8 @@ int ni_create_attr_list(struct ntfs_inode *ni)
+
+ attr = mi_insert_attr(mi, b->type, Add2Ptr(b, name_off),
+ b->name_len, asize, name_off);
+- WARN_ON(!attr);
++ if (!attr)
++ goto out1;
+
+ mi_get_ref(mi, &le_b[nb]->ref);
+ le_b[nb]->id = attr->id;
+@@ -892,17 +894,20 @@ int ni_create_attr_list(struct ntfs_inode *ni)
+ attr->id = le_b[nb]->id;
+
+ /* Remove from primary record. */
+- WARN_ON(!mi_remove_attr(NULL, &ni->mi, b));
++ if (!mi_remove_attr(NULL, &ni->mi, b))
++ goto out1;
+
+ if (to_free <= asize)
+ break;
+ to_free -= asize;
+- WARN_ON(!nb);
++ if (!nb)
++ goto out1;
+ }
+
+ attr = mi_insert_attr(&ni->mi, ATTR_LIST, NULL, 0,
+ lsize + SIZEOF_RESIDENT, SIZEOF_RESIDENT);
+- WARN_ON(!attr);
++ if (!attr)
++ goto out1;
+
+ attr->non_res = 0;
+ attr->flags = 0;
+@@ -922,9 +927,10 @@ int ni_create_attr_list(struct ntfs_inode *ni)
+ kfree(ni->attr_list.le);
+ ni->attr_list.le = NULL;
+ ni->attr_list.size = 0;
++ return err;
+
+ out:
+- return err;
++ return 0;
+ }
+
+ /*
+--
+2.40.1
+
--- /dev/null
+From 344458b6a9215d0aa365b4ffb2d809aab9af101c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Mar 2023 21:22:11 +0800
+Subject: fs: ntfs3: Fix possible null-pointer dereferences in mi_read()
+
+From: Jia-Ju Bai <baijiaju@buaa.edu.cn>
+
+[ Upstream commit 97498cd610c0d030a7bd49a7efad974790661162 ]
+
+In a previous commit 2681631c2973 ("fs/ntfs3: Add null pointer check to
+attr_load_runs_vcn"), ni can be NULL in attr_load_runs_vcn(), and thus it
+should be checked before being used.
+
+However, in the call stack of this commit, mft_ni in mi_read() is
+aliased with ni in attr_load_runs_vcn(), and it is also used in
+mi_read() at two places:
+
+mi_read()
+ rw_lock = &mft_ni->file.run_lock -> No check
+ attr_load_runs_vcn(mft_ni, ...)
+ ni (namely mft_ni) is checked in the previous commit
+ attr_load_runs_vcn(..., &mft_ni->file.run) -> No check
+
+Thus, to avoid possible null-pointer dereferences, the related checks
+should be added.
+
+These bugs are reported by a static analysis tool implemented by myself,
+and they are found by extending a known bug fixed in the previous commit.
+Thus, they could be theoretical bugs.
+
+Signed-off-by: Jia-Ju Bai <baijiaju@buaa.edu.cn>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/record.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ntfs3/record.c b/fs/ntfs3/record.c
+index af1e4b364ea8e..07037ec773ac8 100644
+--- a/fs/ntfs3/record.c
++++ b/fs/ntfs3/record.c
+@@ -124,7 +124,7 @@ int mi_read(struct mft_inode *mi, bool is_mft)
+ struct rw_semaphore *rw_lock = NULL;
+
+ if (is_mounted(sbi)) {
+- if (!is_mft) {
++ if (!is_mft && mft_ni) {
+ rw_lock = &mft_ni->file.run_lock;
+ down_read(rw_lock);
+ }
+@@ -148,7 +148,7 @@ int mi_read(struct mft_inode *mi, bool is_mft)
+ ni_lock(mft_ni);
+ down_write(rw_lock);
+ }
+- err = attr_load_runs_vcn(mft_ni, ATTR_DATA, NULL, 0, &mft_ni->file.run,
++ err = attr_load_runs_vcn(mft_ni, ATTR_DATA, NULL, 0, run,
+ vbo >> sbi->cluster_bits);
+ if (rw_lock) {
+ up_write(rw_lock);
+--
+2.40.1
+
--- /dev/null
+From 6f7bcf8c79142e15df1bfc9e3785f872accc1e08 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 May 2023 11:36:28 +0400
+Subject: fs/ntfs3: Mark ntfs dirty when on-disk struct is corrupted
+
+From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+
+[ Upstream commit e0f363a98830e8d7d70fbaf91c07ae0b7c57aafe ]
+
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/fsntfs.c | 2 +-
+ fs/ntfs3/index.c | 6 ++++++
+ fs/ntfs3/ntfs_fs.h | 2 ++
+ fs/ntfs3/record.c | 6 ++++++
+ 4 files changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c
+index b6e22bcb929ba..829b62d3bb889 100644
+--- a/fs/ntfs3/fsntfs.c
++++ b/fs/ntfs3/fsntfs.c
+@@ -154,7 +154,7 @@ int ntfs_fix_post_read(struct NTFS_RECORD_HEADER *rhdr, size_t bytes,
+ /* Check errors. */
+ if ((fo & 1) || fo + fn * sizeof(short) > SECTOR_SIZE || !fn-- ||
+ fn * SECTOR_SIZE > bytes) {
+- return -EINVAL; /* Native chkntfs returns ok! */
++ return -E_NTFS_CORRUPT;
+ }
+
+ /* Get fixup pointer. */
+diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c
+index 9e9a9ffd92958..495cfb37962fa 100644
+--- a/fs/ntfs3/index.c
++++ b/fs/ntfs3/index.c
+@@ -1103,6 +1103,12 @@ int indx_read(struct ntfs_index *indx, struct ntfs_inode *ni, CLST vbn,
+ *node = in;
+
+ out:
++ if (err == -E_NTFS_CORRUPT) {
++ ntfs_inode_err(&ni->vfs_inode, "directory corrupted");
++ ntfs_set_state(ni->mi.sbi, NTFS_DIRTY_ERROR);
++ err = -EINVAL;
++ }
++
+ if (ib != in->index)
+ kfree(ib);
+
+diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h
+index 24227b2e1b2b0..8c9abaf139e67 100644
+--- a/fs/ntfs3/ntfs_fs.h
++++ b/fs/ntfs3/ntfs_fs.h
+@@ -53,6 +53,8 @@ enum utf16_endian;
+ #define E_NTFS_NONRESIDENT 556
+ /* NTFS specific error code about punch hole. */
+ #define E_NTFS_NOTALIGNED 557
++/* NTFS specific error code when on-disk struct is corrupted. */
++#define E_NTFS_CORRUPT 558
+
+
+ /* sbi->flags */
+diff --git a/fs/ntfs3/record.c b/fs/ntfs3/record.c
+index 07037ec773ac8..ba336c7280b85 100644
+--- a/fs/ntfs3/record.c
++++ b/fs/ntfs3/record.c
+@@ -180,6 +180,12 @@ int mi_read(struct mft_inode *mi, bool is_mft)
+ return 0;
+
+ out:
++ if (err == -E_NTFS_CORRUPT) {
++ ntfs_err(sbi->sb, "mft corrupted");
++ ntfs_set_state(sbi, NTFS_DIRTY_ERROR);
++ err = -EINVAL;
++ }
++
+ return err;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 3befa50b484177925400198b0e2d496e143cdb79 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 11:06:37 +0800
+Subject: gfs2: Fix possible data races in gfs2_show_options()
+
+From: Tuo Li <islituo@gmail.com>
+
+[ Upstream commit 6fa0a72cbbe45db4ed967a51f9e6f4e3afe61d20 ]
+
+Some fields such as gt_logd_secs of the struct gfs2_tune are accessed
+without holding the lock gt_spin in gfs2_show_options():
+
+ val = sdp->sd_tune.gt_logd_secs;
+ if (val != 30)
+ seq_printf(s, ",commit=%d", val);
+
+And thus can cause data races when gfs2_show_options() and other functions
+such as gfs2_reconfigure() are concurrently executed:
+
+ spin_lock(>->gt_spin);
+ gt->gt_logd_secs = newargs->ar_commit;
+
+To fix these possible data races, the lock sdp->sd_tune.gt_spin is
+acquired before accessing the fields of gfs2_tune and released after these
+accesses.
+
+Further changes by Andreas:
+
+- Don't hold the spin lock over the seq_printf operations.
+
+Reported-by: BassCheck <bass@buaa.edu.cn>
+Signed-off-by: Tuo Li <islituo@gmail.com>
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/super.c | 26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
+index 9d27aa8bd2bc6..44c564f0bc622 100644
+--- a/fs/gfs2/super.c
++++ b/fs/gfs2/super.c
+@@ -981,7 +981,14 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root)
+ {
+ struct gfs2_sbd *sdp = root->d_sb->s_fs_info;
+ struct gfs2_args *args = &sdp->sd_args;
+- int val;
++ unsigned int logd_secs, statfs_slow, statfs_quantum, quota_quantum;
++
++ spin_lock(&sdp->sd_tune.gt_spin);
++ logd_secs = sdp->sd_tune.gt_logd_secs;
++ quota_quantum = sdp->sd_tune.gt_quota_quantum;
++ statfs_quantum = sdp->sd_tune.gt_statfs_quantum;
++ statfs_slow = sdp->sd_tune.gt_statfs_slow;
++ spin_unlock(&sdp->sd_tune.gt_spin);
+
+ if (is_ancestor(root, sdp->sd_master_dir))
+ seq_puts(s, ",meta");
+@@ -1036,17 +1043,14 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root)
+ }
+ if (args->ar_discard)
+ seq_puts(s, ",discard");
+- val = sdp->sd_tune.gt_logd_secs;
+- if (val != 30)
+- seq_printf(s, ",commit=%d", val);
+- val = sdp->sd_tune.gt_statfs_quantum;
+- if (val != 30)
+- seq_printf(s, ",statfs_quantum=%d", val);
+- else if (sdp->sd_tune.gt_statfs_slow)
++ if (logd_secs != 30)
++ seq_printf(s, ",commit=%d", logd_secs);
++ if (statfs_quantum != 30)
++ seq_printf(s, ",statfs_quantum=%d", statfs_quantum);
++ else if (statfs_slow)
+ seq_puts(s, ",statfs_quantum=0");
+- val = sdp->sd_tune.gt_quota_quantum;
+- if (val != 60)
+- seq_printf(s, ",quota_quantum=%d", val);
++ if (quota_quantum != 60)
++ seq_printf(s, ",quota_quantum=%d", quota_quantum);
+ if (args->ar_statfs_percent)
+ seq_printf(s, ",statfs_percent=%d", args->ar_statfs_percent);
+ if (args->ar_errors != GFS2_ERRORS_DEFAULT) {
+--
+2.40.1
+
--- /dev/null
+From b6c43606efac4fb518637c7b5e3c6a1b7fb52402 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 08:26:41 +0800
+Subject: HID: intel-ish-hid: ipc: Add Arrow Lake PCI device ID
+
+From: Even Xu <even.xu@intel.com>
+
+[ Upstream commit 4982126e3029cd59fbd1da0d9cc0365a0585fe64 ]
+
+Add device ID of Arrow Lake-H into ishtp support list.
+
+Signed-off-by: Even Xu <even.xu@intel.com>
+Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/intel-ish-hid/ipc/hw-ish.h | 1 +
+ drivers/hid/intel-ish-hid/ipc/pci-ish.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/drivers/hid/intel-ish-hid/ipc/hw-ish.h b/drivers/hid/intel-ish-hid/ipc/hw-ish.h
+index fc108f19a64c3..e99f3a3c65e15 100644
+--- a/drivers/hid/intel-ish-hid/ipc/hw-ish.h
++++ b/drivers/hid/intel-ish-hid/ipc/hw-ish.h
+@@ -33,6 +33,7 @@
+ #define ADL_N_DEVICE_ID 0x54FC
+ #define RPL_S_DEVICE_ID 0x7A78
+ #define MTL_P_DEVICE_ID 0x7E45
++#define ARL_H_DEVICE_ID 0x7745
+
+ #define REVISION_ID_CHT_A0 0x6
+ #define REVISION_ID_CHT_Ax_SI 0x0
+diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
+index 7120b30ac51d0..55cb25038e632 100644
+--- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c
++++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
+@@ -44,6 +44,7 @@ static const struct pci_device_id ish_pci_tbl[] = {
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ADL_N_DEVICE_ID)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, RPL_S_DEVICE_ID)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MTL_P_DEVICE_ID)},
++ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ARL_H_DEVICE_ID)},
+ {0, }
+ };
+ MODULE_DEVICE_TABLE(pci, ish_pci_tbl);
+--
+2.40.1
+
--- /dev/null
+From b42ba4a2fda182ff1f775e5ae91abda587ab590e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 15:44:28 +0100
+Subject: HID: logitech-hidpp: Add USB and Bluetooth IDs for the Logitech G915
+ TKL Keyboard
+
+From: stuarthayhurst <stuart.a.hayhurst@gmail.com>
+
+[ Upstream commit 48aea8b445c422a372cf15915101035a47105421 ]
+
+Adds the USB and Bluetooth IDs for the Logitech G915 TKL keyboard, for device detection
+For this device, this provides battery reporting on top of hid-generic
+
+Reviewed-by: Bastien Nocera <hadess@hadess.net>
+Signed-off-by: Stuart Hayhurst <stuart.a.hayhurst@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-logitech-hidpp.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
+index 0b4204b9a253c..97eefb77f6014 100644
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -4403,6 +4403,8 @@ static const struct hid_device_id hidpp_devices[] = {
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC086) },
+ { /* Logitech G903 Hero Gaming Mouse over USB */
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC091) },
++ { /* Logitech G915 TKL Keyboard over USB */
++ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC343) },
+ { /* Logitech G920 Wheel over USB */
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL),
+ .driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS},
+@@ -4418,6 +4420,8 @@ static const struct hid_device_id hidpp_devices[] = {
+ { /* MX5500 keyboard over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb30b),
+ .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
++ { /* Logitech G915 TKL keyboard over Bluetooth */
++ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb35f) },
+ { /* M-RCQ142 V470 Cordless Laser Mouse over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb008) },
+ { /* MX Master mouse over Bluetooth */
+--
+2.40.1
+
--- /dev/null
+From 25ec888e27fcf1a21e02bbd0e043ad84990e04bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 May 2023 08:48:06 -0700
+Subject: igc: read before write to SRRCTL register
+
+From: Song Yoong Siang <yoong.siang.song@intel.com>
+
+[ Upstream commit 3ce29c17dc847bf4245e16aad78a7617afa96297 ]
+
+igc_configure_rx_ring() function will be called as part of XDP program
+setup. If Rx hardware timestamp is enabled prio to XDP program setup,
+this timestamp enablement will be overwritten when buffer size is
+written into SRRCTL register.
+
+Thus, this commit read the register value before write to SRRCTL
+register. This commit is tested by using xdp_hw_metadata bpf selftest
+tool. The tool enables Rx hardware timestamp and then attach XDP program
+to igc driver. It will display hardware timestamp of UDP packet with
+port number 9092. Below are detail of test steps and results.
+
+Command on DUT:
+ sudo ./xdp_hw_metadata <interface name>
+
+Command on Link Partner:
+ echo -n skb | nc -u -q1 <destination IPv4 addr> 9092
+
+Result before this patch:
+ skb hwtstamp is not found!
+
+Result after this patch:
+ found skb hwtstamp = 1677800973.642836757
+
+Optionally, read PHC to confirm the values obtained are almost the same:
+Command:
+ sudo ./testptp -d /dev/ptp0 -g
+Result:
+ clock time: 1677800973.913598978 or Fri Mar 3 07:49:33 2023
+
+Fixes: fc9df2a0b520 ("igc: Enable RX via AF_XDP zero-copy")
+Cc: <stable@vger.kernel.org> # 5.14+
+Signed-off-by: Song Yoong Siang <yoong.siang.song@intel.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Jesper Dangaard Brouer <brouer@redhat.com>
+Tested-by: Jesper Dangaard Brouer <brouer@redhat.com>
+Tested-by: Naama Meir <naamax.meir@linux.intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc_base.h | 11 ++++++++---
+ drivers/net/ethernet/intel/igc/igc_main.c | 7 +++++--
+ 2 files changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_base.h b/drivers/net/ethernet/intel/igc/igc_base.h
+index ce530f5fd7bda..52849f5e8048d 100644
+--- a/drivers/net/ethernet/intel/igc/igc_base.h
++++ b/drivers/net/ethernet/intel/igc/igc_base.h
+@@ -85,8 +85,13 @@ union igc_adv_rx_desc {
+ #define IGC_RXDCTL_SWFLUSH 0x04000000 /* Receive Software Flush */
+
+ /* SRRCTL bit definitions */
+-#define IGC_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
+-#define IGC_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
+-#define IGC_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
++#define IGC_SRRCTL_BSIZEPKT_MASK GENMASK(6, 0)
++#define IGC_SRRCTL_BSIZEPKT(x) FIELD_PREP(IGC_SRRCTL_BSIZEPKT_MASK, \
++ (x) / 1024) /* in 1 KB resolution */
++#define IGC_SRRCTL_BSIZEHDR_MASK GENMASK(13, 8)
++#define IGC_SRRCTL_BSIZEHDR(x) FIELD_PREP(IGC_SRRCTL_BSIZEHDR_MASK, \
++ (x) / 64) /* in 64 bytes resolution */
++#define IGC_SRRCTL_DESCTYPE_MASK GENMASK(27, 25)
++#define IGC_SRRCTL_DESCTYPE_ADV_ONEBUF FIELD_PREP(IGC_SRRCTL_DESCTYPE_MASK, 1)
+
+ #endif /* _IGC_BASE_H */
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index d877dc0f87f71..2f3947cf513bd 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -675,8 +675,11 @@ static void igc_configure_rx_ring(struct igc_adapter *adapter,
+ else
+ buf_size = IGC_RXBUFFER_2048;
+
+- srrctl = IGC_RX_HDR_LEN << IGC_SRRCTL_BSIZEHDRSIZE_SHIFT;
+- srrctl |= buf_size >> IGC_SRRCTL_BSIZEPKT_SHIFT;
++ srrctl = rd32(IGC_SRRCTL(reg_idx));
++ srrctl &= ~(IGC_SRRCTL_BSIZEPKT_MASK | IGC_SRRCTL_BSIZEHDR_MASK |
++ IGC_SRRCTL_DESCTYPE_MASK);
++ srrctl |= IGC_SRRCTL_BSIZEHDR(IGC_RX_HDR_LEN);
++ srrctl |= IGC_SRRCTL_BSIZEPKT(buf_size);
+ srrctl |= IGC_SRRCTL_DESCTYPE_ADV_ONEBUF;
+
+ wr32(IGC_SRRCTL(reg_idx), srrctl);
+--
+2.40.1
+
--- /dev/null
+From d3bb2c13f99e10184e11e48ac683821e4a9c9ea6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 10:11:35 -0400
+Subject: iommu/amd: Introduce Disable IRTE Caching Support
+
+From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+
+[ Upstream commit 66419036f68a838c00cbccacd6cb2e99da6e5710 ]
+
+An Interrupt Remapping Table (IRT) stores interrupt remapping configuration
+for each device. In a normal operation, the AMD IOMMU caches the table
+to optimize subsequent data accesses. This requires the IOMMU driver to
+invalidate IRT whenever it updates the table. The invalidation process
+includes issuing an INVALIDATE_INTERRUPT_TABLE command following by
+a COMPLETION_WAIT command.
+
+However, there are cases in which the IRT is updated at a high rate.
+For example, for IOMMU AVIC, the IRTE[IsRun] bit is updated on every
+vcpu scheduling (i.e. amd_iommu_update_ga()). On system with large
+amount of vcpus and VFIO PCI pass-through devices, the invalidation
+process could potentially become a performance bottleneck.
+
+Introducing a new kernel boot option:
+
+ amd_iommu=irtcachedis
+
+which disables IRTE caching by setting the IRTCachedis bit in each IOMMU
+Control register, and bypass the IRT invalidation process.
+
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Co-developed-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
+Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
+Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+Link: https://lore.kernel.org/r/20230530141137.14376-4-suravee.suthikulpanit@amd.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../admin-guide/kernel-parameters.txt | 1 +
+ drivers/iommu/amd/amd_iommu_types.h | 4 +++
+ drivers/iommu/amd/init.c | 36 +++++++++++++++++++
+ 3 files changed, 41 insertions(+)
+
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
+index 286be425f3bfa..882b6198dd0d1 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -323,6 +323,7 @@
+ option with care.
+ pgtbl_v1 - Use v1 page table for DMA-API (Default).
+ pgtbl_v2 - Use v2 page table for DMA-API.
++ irtcachedis - Disable Interrupt Remapping Table (IRT) caching.
+
+ amd_iommu_dump= [HW,X86-64]
+ Enable AMD IOMMU driver option to dump the ACPI table
+diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h
+index 5ecc17240eff5..f5e9377b55212 100644
+--- a/drivers/iommu/amd/amd_iommu_types.h
++++ b/drivers/iommu/amd/amd_iommu_types.h
+@@ -172,6 +172,7 @@
+ #define CONTROL_GAINT_EN 29
+ #define CONTROL_XT_EN 50
+ #define CONTROL_INTCAPXT_EN 51
++#define CONTROL_IRTCACHEDIS 59
+ #define CONTROL_SNPAVIC_EN 61
+
+ #define CTRL_INV_TO_MASK (7 << CONTROL_INV_TIMEOUT)
+@@ -708,6 +709,9 @@ struct amd_iommu {
+ /* if one, we need to send a completion wait command */
+ bool need_sync;
+
++ /* true if disable irte caching */
++ bool irtcachedis_enabled;
++
+ /* Handle for IOMMU core code */
+ struct iommu_device iommu;
+
+diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
+index b0af8b5967e0d..f6e64c9858021 100644
+--- a/drivers/iommu/amd/init.c
++++ b/drivers/iommu/amd/init.c
+@@ -160,6 +160,7 @@ static int amd_iommu_xt_mode = IRQ_REMAP_XAPIC_MODE;
+ static bool amd_iommu_detected;
+ static bool amd_iommu_disabled __initdata;
+ static bool amd_iommu_force_enable __initdata;
++static bool amd_iommu_irtcachedis;
+ static int amd_iommu_target_ivhd_type;
+
+ /* Global EFR and EFR2 registers */
+@@ -477,6 +478,9 @@ static void iommu_disable(struct amd_iommu *iommu)
+
+ /* Disable IOMMU hardware itself */
+ iommu_feature_disable(iommu, CONTROL_IOMMU_EN);
++
++ /* Clear IRTE cache disabling bit */
++ iommu_feature_disable(iommu, CONTROL_IRTCACHEDIS);
+ }
+
+ /*
+@@ -2700,6 +2704,33 @@ static void iommu_enable_ga(struct amd_iommu *iommu)
+ #endif
+ }
+
++static void iommu_disable_irtcachedis(struct amd_iommu *iommu)
++{
++ iommu_feature_disable(iommu, CONTROL_IRTCACHEDIS);
++}
++
++static void iommu_enable_irtcachedis(struct amd_iommu *iommu)
++{
++ u64 ctrl;
++
++ if (!amd_iommu_irtcachedis)
++ return;
++
++ /*
++ * Note:
++ * The support for IRTCacheDis feature is dertermined by
++ * checking if the bit is writable.
++ */
++ iommu_feature_enable(iommu, CONTROL_IRTCACHEDIS);
++ ctrl = readq(iommu->mmio_base + MMIO_CONTROL_OFFSET);
++ ctrl &= (1ULL << CONTROL_IRTCACHEDIS);
++ if (ctrl)
++ iommu->irtcachedis_enabled = true;
++ pr_info("iommu%d (%#06x) : IRT cache is %s\n",
++ iommu->index, iommu->devid,
++ iommu->irtcachedis_enabled ? "disabled" : "enabled");
++}
++
+ static void early_enable_iommu(struct amd_iommu *iommu)
+ {
+ iommu_disable(iommu);
+@@ -2710,6 +2741,7 @@ static void early_enable_iommu(struct amd_iommu *iommu)
+ iommu_set_exclusion_range(iommu);
+ iommu_enable_ga(iommu);
+ iommu_enable_xt(iommu);
++ iommu_enable_irtcachedis(iommu);
+ iommu_enable(iommu);
+ iommu_flush_all_caches(iommu);
+ }
+@@ -2760,10 +2792,12 @@ static void early_enable_iommus(void)
+ for_each_iommu(iommu) {
+ iommu_disable_command_buffer(iommu);
+ iommu_disable_event_buffer(iommu);
++ iommu_disable_irtcachedis(iommu);
+ iommu_enable_command_buffer(iommu);
+ iommu_enable_event_buffer(iommu);
+ iommu_enable_ga(iommu);
+ iommu_enable_xt(iommu);
++ iommu_enable_irtcachedis(iommu);
+ iommu_set_device_table(iommu);
+ iommu_flush_all_caches(iommu);
+ }
+@@ -3411,6 +3445,8 @@ static int __init parse_amd_iommu_options(char *str)
+ amd_iommu_pgtable = AMD_IOMMU_V1;
+ } else if (strncmp(str, "pgtbl_v2", 8) == 0) {
+ amd_iommu_pgtable = AMD_IOMMU_V2;
++ } else if (strncmp(str, "irtcachedis", 11) == 0) {
++ amd_iommu_irtcachedis = true;
+ } else {
+ pr_notice("Unknown option - '%s'\n", str);
+ }
+--
+2.40.1
+
--- /dev/null
+From 4c8776ea7c7951d87aa4024e28be4137f58afcf6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Jun 2023 10:50:36 +0200
+Subject: iopoll: Call cpu_relax() in busy loops
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit b407460ee99033503993ac7437d593451fcdfe44 ]
+
+It is considered good practice to call cpu_relax() in busy loops, see
+Documentation/process/volatile-considered-harmful.rst. This can not
+only lower CPU power consumption or yield to a hyperthreaded twin
+processor, but also allows an architecture to mitigate hardware issues
+(e.g. ARM Erratum 754327 for Cortex-A9 prior to r2p0) in the
+architecture-specific cpu_relax() implementation.
+
+In addition, cpu_relax() is also a compiler barrier. It is not
+immediately obvious that the @op argument "function" will result in an
+actual function call (e.g. in case of inlining).
+
+Where a function call is a C sequence point, this is lost on inlining.
+Therefore, with agressive enough optimization it might be possible for
+the compiler to hoist the:
+
+ (val) = op(args);
+
+"load" out of the loop because it doesn't see the value changing. The
+addition of cpu_relax() would inhibit this.
+
+As the iopoll helpers lack calls to cpu_relax(), people are sometimes
+reluctant to use them, and may fall back to open-coded polling loops
+(including cpu_relax() calls) instead.
+
+Fix this by adding calls to cpu_relax() to the iopoll helpers:
+ - For the non-atomic case, it is sufficient to call cpu_relax() in
+ case of a zero sleep-between-reads value, as a call to
+ usleep_range() is a safe barrier otherwise. However, it doesn't
+ hurt to add the call regardless, for simplicity, and for similarity
+ with the atomic case below.
+ - For the atomic case, cpu_relax() must be called regardless of the
+ sleep-between-reads value, as there is no guarantee all
+ architecture-specific implementations of udelay() handle this.
+
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Tony Lindgren <tony@atomide.com>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Link: https://lore.kernel.org/r/45c87bec3397fdd704376807f0eec5cc71be440f.1685692810.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/iopoll.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/linux/iopoll.h b/include/linux/iopoll.h
+index 2c8860e406bd8..0417360a6db9b 100644
+--- a/include/linux/iopoll.h
++++ b/include/linux/iopoll.h
+@@ -53,6 +53,7 @@
+ } \
+ if (__sleep_us) \
+ usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
++ cpu_relax(); \
+ } \
+ (cond) ? 0 : -ETIMEDOUT; \
+ })
+@@ -95,6 +96,7 @@
+ } \
+ if (__delay_us) \
+ udelay(__delay_us); \
++ cpu_relax(); \
+ } \
+ (cond) ? 0 : -ETIMEDOUT; \
+ })
+--
+2.40.1
+
--- /dev/null
+From 4fda51cefffa124c3acc6bb65f0faf1550974632 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Jul 2023 08:06:57 +0100
+Subject: KVM: arm64: vgic-v4: Make the doorbell request robust w.r.t
+ preemption
+
+From: Marc Zyngier <maz@kernel.org>
+
+[ Upstream commit b321c31c9b7b309dcde5e8854b741c8e6a9a05f0 ]
+
+Xiang reports that VMs occasionally fail to boot on GICv4.1 systems when
+running a preemptible kernel, as it is possible that a vCPU is blocked
+without requesting a doorbell interrupt.
+
+The issue is that any preemption that occurs between vgic_v4_put() and
+schedule() on the block path will mark the vPE as nonresident and *not*
+request a doorbell irq. This occurs because when the vcpu thread is
+resumed on its way to block, vcpu_load() will make the vPE resident
+again. Once the vcpu actually blocks, we don't request a doorbell
+anymore, and the vcpu won't be woken up on interrupt delivery.
+
+Fix it by tracking that we're entering WFI, and key the doorbell
+request on that flag. This allows us not to make the vPE resident
+when going through a preempt/schedule cycle, meaning we don't lose
+any state.
+
+Cc: stable@vger.kernel.org
+Fixes: 8e01d9a396e6 ("KVM: arm64: vgic-v4: Move the GICv4 residency flow to be driven by vcpu_load/put")
+Reported-by: Xiang Chen <chenxiang66@hisilicon.com>
+Suggested-by: Zenghui Yu <yuzenghui@huawei.com>
+Tested-by: Xiang Chen <chenxiang66@hisilicon.com>
+Co-developed-by: Oliver Upton <oliver.upton@linux.dev>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Acked-by: Zenghui Yu <yuzenghui@huawei.com>
+Link: https://lore.kernel.org/r/20230713070657.3873244-1-maz@kernel.org
+Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/kvm_host.h | 2 ++
+ arch/arm64/kvm/arm.c | 6 ++++--
+ arch/arm64/kvm/vgic/vgic-v3.c | 2 +-
+ arch/arm64/kvm/vgic/vgic-v4.c | 7 +++++--
+ include/kvm/arm_vgic.h | 2 +-
+ 5 files changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
+index b5a8e8b3c691c..577cf444c1135 100644
+--- a/arch/arm64/include/asm/kvm_host.h
++++ b/arch/arm64/include/asm/kvm_host.h
+@@ -559,6 +559,8 @@ struct kvm_vcpu_arch {
+ #define SYSREGS_ON_CPU __vcpu_single_flag(sflags, BIT(4))
+ /* Software step state is Active-pending */
+ #define DBG_SS_ACTIVE_PENDING __vcpu_single_flag(sflags, BIT(5))
++/* WFI instruction trapped */
++#define IN_WFI __vcpu_single_flag(sflags, BIT(7))
+
+
+ /* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */
+diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
+index 35481d51aada8..6cc380a15eb76 100644
+--- a/arch/arm64/kvm/arm.c
++++ b/arch/arm64/kvm/arm.c
+@@ -692,13 +692,15 @@ void kvm_vcpu_wfi(struct kvm_vcpu *vcpu)
+ */
+ preempt_disable();
+ kvm_vgic_vmcr_sync(vcpu);
+- vgic_v4_put(vcpu, true);
++ vcpu_set_flag(vcpu, IN_WFI);
++ vgic_v4_put(vcpu);
+ preempt_enable();
+
+ kvm_vcpu_halt(vcpu);
+ vcpu_clear_flag(vcpu, IN_WFIT);
+
+ preempt_disable();
++ vcpu_clear_flag(vcpu, IN_WFI);
+ vgic_v4_load(vcpu);
+ preempt_enable();
+ }
+@@ -766,7 +768,7 @@ static int check_vcpu_requests(struct kvm_vcpu *vcpu)
+ if (kvm_check_request(KVM_REQ_RELOAD_GICv4, vcpu)) {
+ /* The distributor enable bits were changed */
+ preempt_disable();
+- vgic_v4_put(vcpu, false);
++ vgic_v4_put(vcpu);
+ vgic_v4_load(vcpu);
+ preempt_enable();
+ }
+diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
+index f86c3007a319c..1f8eea53e982f 100644
+--- a/arch/arm64/kvm/vgic/vgic-v3.c
++++ b/arch/arm64/kvm/vgic/vgic-v3.c
+@@ -742,7 +742,7 @@ void vgic_v3_put(struct kvm_vcpu *vcpu)
+ {
+ struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
+
+- WARN_ON(vgic_v4_put(vcpu, false));
++ WARN_ON(vgic_v4_put(vcpu));
+
+ vgic_v3_vmcr_sync(vcpu);
+
+diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c
+index c1c28fe680ba3..339a55194b2c6 100644
+--- a/arch/arm64/kvm/vgic/vgic-v4.c
++++ b/arch/arm64/kvm/vgic/vgic-v4.c
+@@ -336,14 +336,14 @@ void vgic_v4_teardown(struct kvm *kvm)
+ its_vm->vpes = NULL;
+ }
+
+-int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db)
++int vgic_v4_put(struct kvm_vcpu *vcpu)
+ {
+ struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe;
+
+ if (!vgic_supports_direct_msis(vcpu->kvm) || !vpe->resident)
+ return 0;
+
+- return its_make_vpe_non_resident(vpe, need_db);
++ return its_make_vpe_non_resident(vpe, !!vcpu_get_flag(vcpu, IN_WFI));
+ }
+
+ int vgic_v4_load(struct kvm_vcpu *vcpu)
+@@ -354,6 +354,9 @@ int vgic_v4_load(struct kvm_vcpu *vcpu)
+ if (!vgic_supports_direct_msis(vcpu->kvm) || vpe->resident)
+ return 0;
+
++ if (vcpu_get_flag(vcpu, IN_WFI))
++ return 0;
++
+ /*
+ * Before making the VPE resident, make sure the redistributor
+ * corresponding to our current CPU expects us here. See the
+diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
+index 4df9e73a8bb5f..1d7d4cffaefc6 100644
+--- a/include/kvm/arm_vgic.h
++++ b/include/kvm/arm_vgic.h
+@@ -429,6 +429,6 @@ int kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int irq,
+
+ int vgic_v4_load(struct kvm_vcpu *vcpu);
+ void vgic_v4_commit(struct kvm_vcpu *vcpu);
+-int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db);
++int vgic_v4_put(struct kvm_vcpu *vcpu);
+
+ #endif /* __KVM_ARM_VGIC_H */
+--
+2.40.1
+
--- /dev/null
+From 487b8ade179dce77d43decafd2cef6ecdce403b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 May 2023 19:17:03 +0800
+Subject: led: qcom-lpg: Fix resource leaks in
+ for_each_available_child_of_node() loops
+
+From: Lu Hongfei <luhongfei@vivo.com>
+
+[ Upstream commit 8f38f8fa7261819eb7d4fb369dc3bfab72259033 ]
+
+Ensure child node references are decremented properly in the error path.
+
+Signed-off-by: Lu Hongfei <luhongfei@vivo.com>
+Link: https://lore.kernel.org/r/20230525111705.3055-1-luhongfei@vivo.com
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/rgb/leds-qcom-lpg.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c
+index f1c2419334e6f..f85a5d65d1314 100644
+--- a/drivers/leds/rgb/leds-qcom-lpg.c
++++ b/drivers/leds/rgb/leds-qcom-lpg.c
+@@ -1112,8 +1112,10 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
+ i = 0;
+ for_each_available_child_of_node(np, child) {
+ ret = lpg_parse_channel(lpg, child, &led->channels[i]);
+- if (ret < 0)
++ if (ret < 0) {
++ of_node_put(child);
+ return ret;
++ }
+
+ info[i].color_index = led->channels[i]->color;
+ info[i].intensity = 0;
+@@ -1291,8 +1293,10 @@ static int lpg_probe(struct platform_device *pdev)
+
+ for_each_available_child_of_node(pdev->dev.of_node, np) {
+ ret = lpg_add_led(lpg, np);
+- if (ret)
++ if (ret) {
++ of_node_put(np);
+ return ret;
++ }
+ }
+
+ for (i = 0; i < lpg->num_channels; i++)
+--
+2.40.1
+
--- /dev/null
+From 84326bc436298d8046716d1cfefed15ad8495cff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 May 2023 00:52:35 +0300
+Subject: media: camss: set VFE bpl_alignment to 16 for sdm845 and sm8250
+
+From: Andrey Konovalov <andrey.konovalov@linaro.org>
+
+[ Upstream commit d5b7eb477c286f6ceccbb38704136eea0e6b09ca ]
+
+From the experiments with camera sensors using SGRBG10_1X10/3280x2464 and
+SRGGB10_1X10/3280x2464 formats, it becomes clear that on sdm845 and sm8250
+VFE outputs the lines padded to a length multiple of 16 bytes. As in the
+current driver the value of the bpl_alignment is set to 8 bytes, the frames
+captured in formats with the bytes-per-line value being not a multiple of
+16 get corrupted.
+
+Set the bpl_alignment of the camss video output device to 16 for sdm845 and
+sm8250 to fix that.
+
+Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
+Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Acked-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/qcom/camss/camss-vfe.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
+index a26e4a5d87b6b..d8cd9b09c20de 100644
+--- a/drivers/media/platform/qcom/camss/camss-vfe.c
++++ b/drivers/media/platform/qcom/camss/camss-vfe.c
+@@ -1540,7 +1540,11 @@ int msm_vfe_register_entities(struct vfe_device *vfe,
+ }
+
+ video_out->ops = &vfe->video_ops;
+- video_out->bpl_alignment = 8;
++ if (vfe->camss->version == CAMSS_845 ||
++ vfe->camss->version == CAMSS_8250)
++ video_out->bpl_alignment = 16;
++ else
++ video_out->bpl_alignment = 8;
+ video_out->line_based = 0;
+ if (i == VFE_LINE_PIX) {
+ video_out->bpl_alignment = 16;
+--
+2.40.1
+
--- /dev/null
+From 04e290e47bad8452453156735410338315bd0ea3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 May 2023 13:11:47 +0100
+Subject: media: platform: mediatek: vpu: fix NULL ptr dereference
+
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+
+[ Upstream commit 3df55cd773e8603b623425cc97b05e542854ad27 ]
+
+If pdev is NULL, then it is still dereferenced.
+
+This fixes this smatch warning:
+
+drivers/media/platform/mediatek/vpu/mtk_vpu.c:570 vpu_load_firmware() warn: address of NULL pointer 'pdev'
+
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Cc: Yunfei Dong <yunfei.dong@mediatek.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/mediatek/vpu/mtk_vpu.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/mediatek/vpu/mtk_vpu.c b/drivers/media/platform/mediatek/vpu/mtk_vpu.c
+index 47b684b92f817..6beab9e86a22a 100644
+--- a/drivers/media/platform/mediatek/vpu/mtk_vpu.c
++++ b/drivers/media/platform/mediatek/vpu/mtk_vpu.c
+@@ -562,15 +562,17 @@ static int load_requested_vpu(struct mtk_vpu *vpu,
+ int vpu_load_firmware(struct platform_device *pdev)
+ {
+ struct mtk_vpu *vpu;
+- struct device *dev = &pdev->dev;
++ struct device *dev;
+ struct vpu_run *run;
+ int ret;
+
+ if (!pdev) {
+- dev_err(dev, "VPU platform device is invalid\n");
++ pr_err("VPU platform device is invalid\n");
+ return -EINVAL;
+ }
+
++ dev = &pdev->dev;
++
+ vpu = platform_get_drvdata(pdev);
+ run = &vpu->run;
+
+--
+2.40.1
+
--- /dev/null
+From 9eb17de4f02998d9f74f097fbb8673cc3a7d939f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Apr 2023 16:17:40 +0800
+Subject: media: v4l2-mem2mem: add lock to protect parameter num_rdy
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yunfei Dong <yunfei.dong@mediatek.com>
+
+[ Upstream commit 56b5c3e67b0f9af3f45cf393be048ee8d8a92694 ]
+
+Getting below error when using KCSAN to check the driver. Adding lock to
+protect parameter num_rdy when getting the value with function:
+v4l2_m2m_num_src_bufs_ready/v4l2_m2m_num_dst_bufs_ready.
+
+kworker/u16:3: [name:report&]BUG: KCSAN: data-race in v4l2_m2m_buf_queue
+kworker/u16:3: [name:report&]
+
+kworker/u16:3: [name:report&]read-write to 0xffffff8105f35b94 of 1 bytes by task 20865 on cpu 7:
+kworker/u16:3: v4l2_m2m_buf_queue+0xd8/0x10c
+
+Signed-off-by: Pina Chen <pina.chen@mediatek.com>
+Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/media/v4l2-mem2mem.h | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
+index bb9de6a899e07..d6c8eb2b52019 100644
+--- a/include/media/v4l2-mem2mem.h
++++ b/include/media/v4l2-mem2mem.h
+@@ -593,7 +593,14 @@ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx,
+ static inline
+ unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
+ {
+- return m2m_ctx->out_q_ctx.num_rdy;
++ unsigned int num_buf_rdy;
++ unsigned long flags;
++
++ spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
++ num_buf_rdy = m2m_ctx->out_q_ctx.num_rdy;
++ spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
++
++ return num_buf_rdy;
+ }
+
+ /**
+@@ -605,7 +612,14 @@ unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
+ static inline
+ unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
+ {
+- return m2m_ctx->cap_q_ctx.num_rdy;
++ unsigned int num_buf_rdy;
++ unsigned long flags;
++
++ spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags);
++ num_buf_rdy = m2m_ctx->cap_q_ctx.num_rdy;
++ spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags);
++
++ return num_buf_rdy;
+ }
+
+ /**
+--
+2.40.1
+
--- /dev/null
+From 2a9e2e4a3b7ba0da62450d8f6dcd88aef8ece527 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jun 2023 09:45:33 +0900
+Subject: mmc: sdhci-f-sdh30: Replace with sdhci_pltfm
+
+From: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+
+[ Upstream commit 5def5c1c15bf22934ee227af85c1716762f3829f ]
+
+Even if sdhci_pltfm_pmops is specified for PM, this driver doesn't apply
+sdhci_pltfm, so the structure is not correctly referenced in PM functions.
+This applies sdhci_pltfm to this driver to fix this issue.
+
+- Call sdhci_pltfm_init() instead of sdhci_alloc_host() and
+ other functions that covered by sdhci_pltfm.
+- Move ops and quirks to sdhci_pltfm_data
+- Replace sdhci_priv() with own private function sdhci_f_sdh30_priv().
+
+Fixes: 87a507459f49 ("mmc: sdhci: host: add new f_sdh30")
+Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20230630004533.26644-1-hayashi.kunihiko@socionext.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci_f_sdh30.c | 60 ++++++++++++++------------------
+ 1 file changed, 27 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c
+index 6c4f43e112826..8876fd1c7eee0 100644
+--- a/drivers/mmc/host/sdhci_f_sdh30.c
++++ b/drivers/mmc/host/sdhci_f_sdh30.c
+@@ -26,9 +26,16 @@ struct f_sdhost_priv {
+ bool enable_cmd_dat_delay;
+ };
+
++static void *sdhci_f_sdhost_priv(struct sdhci_host *host)
++{
++ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
++
++ return sdhci_pltfm_priv(pltfm_host);
++}
++
+ static void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host)
+ {
+- struct f_sdhost_priv *priv = sdhci_priv(host);
++ struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host);
+ u32 ctrl = 0;
+
+ usleep_range(2500, 3000);
+@@ -61,7 +68,7 @@ static unsigned int sdhci_f_sdh30_get_min_clock(struct sdhci_host *host)
+
+ static void sdhci_f_sdh30_reset(struct sdhci_host *host, u8 mask)
+ {
+- struct f_sdhost_priv *priv = sdhci_priv(host);
++ struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host);
+ u32 ctl;
+
+ if (sdhci_readw(host, SDHCI_CLOCK_CONTROL) == 0)
+@@ -85,30 +92,32 @@ static const struct sdhci_ops sdhci_f_sdh30_ops = {
+ .set_uhs_signaling = sdhci_set_uhs_signaling,
+ };
+
++static const struct sdhci_pltfm_data sdhci_f_sdh30_pltfm_data = {
++ .ops = &sdhci_f_sdh30_ops,
++ .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
++ | SDHCI_QUIRK_INVERTED_WRITE_PROTECT,
++ .quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE
++ | SDHCI_QUIRK2_TUNING_WORK_AROUND,
++};
++
+ static int sdhci_f_sdh30_probe(struct platform_device *pdev)
+ {
+ struct sdhci_host *host;
+ struct device *dev = &pdev->dev;
+- int irq, ctrl = 0, ret = 0;
++ int ctrl = 0, ret = 0;
+ struct f_sdhost_priv *priv;
++ struct sdhci_pltfm_host *pltfm_host;
+ u32 reg = 0;
+
+- irq = platform_get_irq(pdev, 0);
+- if (irq < 0)
+- return irq;
+-
+- host = sdhci_alloc_host(dev, sizeof(struct f_sdhost_priv));
++ host = sdhci_pltfm_init(pdev, &sdhci_f_sdh30_pltfm_data,
++ sizeof(struct f_sdhost_priv));
+ if (IS_ERR(host))
+ return PTR_ERR(host);
+
+- priv = sdhci_priv(host);
++ pltfm_host = sdhci_priv(host);
++ priv = sdhci_pltfm_priv(pltfm_host);
+ priv->dev = dev;
+
+- host->quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
+- SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
+- host->quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE |
+- SDHCI_QUIRK2_TUNING_WORK_AROUND;
+-
+ priv->enable_cmd_dat_delay = device_property_read_bool(dev,
+ "fujitsu,cmd-dat-delay-select");
+
+@@ -116,18 +125,6 @@ static int sdhci_f_sdh30_probe(struct platform_device *pdev)
+ if (ret)
+ goto err;
+
+- platform_set_drvdata(pdev, host);
+-
+- host->hw_name = "f_sdh30";
+- host->ops = &sdhci_f_sdh30_ops;
+- host->irq = irq;
+-
+- host->ioaddr = devm_platform_ioremap_resource(pdev, 0);
+- if (IS_ERR(host->ioaddr)) {
+- ret = PTR_ERR(host->ioaddr);
+- goto err;
+- }
+-
+ if (dev_of_node(dev)) {
+ sdhci_get_of_property(pdev);
+
+@@ -182,23 +179,20 @@ static int sdhci_f_sdh30_probe(struct platform_device *pdev)
+ err_clk:
+ clk_disable_unprepare(priv->clk_iface);
+ err:
+- sdhci_free_host(host);
++ sdhci_pltfm_free(pdev);
++
+ return ret;
+ }
+
+ static int sdhci_f_sdh30_remove(struct platform_device *pdev)
+ {
+ struct sdhci_host *host = platform_get_drvdata(pdev);
+- struct f_sdhost_priv *priv = sdhci_priv(host);
+-
+- sdhci_remove_host(host, readl(host->ioaddr + SDHCI_INT_STATUS) ==
+- 0xffffffff);
++ struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host);
+
+ clk_disable_unprepare(priv->clk_iface);
+ clk_disable_unprepare(priv->clk);
+
+- sdhci_free_host(host);
+- platform_set_drvdata(pdev, NULL);
++ sdhci_pltfm_unregister(pdev);
+
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From 6728092aaf480a3969172b47cc06f41fefadcae6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Aug 2023 14:13:46 -0500
+Subject: net: phy: at803x: fix the wol setting functions
+
+From: Li Yang <leoyang.li@nxp.com>
+
+[ Upstream commit e58f30246c35c126c7571065b33bee4b3b1d2ef8 ]
+
+In commit 7beecaf7d507 ("net: phy: at803x: improve the WOL feature"), it
+seems not correct to use a wol_en bit in a 1588 Control Register which is
+only available on AR8031/AR8033(share the same phy_id) to determine if WoL
+is enabled. Change it back to use AT803X_INTR_ENABLE_WOL for determining
+the WoL status which is applicable on all chips supporting wol. Also update
+the at803x_set_wol() function to only update the 1588 register on chips
+having it. After this change, disabling wol at probe from commit
+d7cd5e06c9dd ("net: phy: at803x: disable WOL at probe") is no longer
+needed. Change it to just disable the WoL bit in 1588 register for
+AR8031/AR8033 to be aligned with AT803X_INTR_ENABLE_WOL in probe.
+
+Fixes: 7beecaf7d507 ("net: phy: at803x: improve the WOL feature")
+Signed-off-by: Li Yang <leoyang.li@nxp.com>
+Reviewed-by: Viorel Suman <viorel.suman@nxp.com>
+Reviewed-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/at803x.c | 45 ++++++++++++++++++++++------------------
+ 1 file changed, 25 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
+index e351fa8b84b7d..edd4b1e58d965 100644
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -460,21 +460,27 @@ static int at803x_set_wol(struct phy_device *phydev,
+ phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i],
+ mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
+
+- /* Enable WOL function */
+- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL,
+- 0, AT803X_WOL_EN);
+- if (ret)
+- return ret;
++ /* Enable WOL function for 1588 */
++ if (phydev->drv->phy_id == ATH8031_PHY_ID) {
++ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
++ AT803X_PHY_MMD3_WOL_CTRL,
++ 0, AT803X_WOL_EN);
++ if (ret)
++ return ret;
++ }
+ /* Enable WOL interrupt */
+ ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL);
+ if (ret)
+ return ret;
+ } else {
+- /* Disable WoL function */
+- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL,
+- AT803X_WOL_EN, 0);
+- if (ret)
+- return ret;
++ /* Disable WoL function for 1588 */
++ if (phydev->drv->phy_id == ATH8031_PHY_ID) {
++ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
++ AT803X_PHY_MMD3_WOL_CTRL,
++ AT803X_WOL_EN, 0);
++ if (ret)
++ return ret;
++ }
+ /* Disable WOL interrupt */
+ ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0);
+ if (ret)
+@@ -509,11 +515,11 @@ static void at803x_get_wol(struct phy_device *phydev,
+ wol->supported = WAKE_MAGIC;
+ wol->wolopts = 0;
+
+- value = phy_read_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL);
++ value = phy_read(phydev, AT803X_INTR_ENABLE);
+ if (value < 0)
+ return;
+
+- if (value & AT803X_WOL_EN)
++ if (value & AT803X_INTR_ENABLE_WOL)
+ wol->wolopts |= WAKE_MAGIC;
+ }
+
+@@ -859,9 +865,6 @@ static int at803x_probe(struct phy_device *phydev)
+ if (phydev->drv->phy_id == ATH8031_PHY_ID) {
+ int ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
+ int mode_cfg;
+- struct ethtool_wolinfo wol = {
+- .wolopts = 0,
+- };
+
+ if (ccr < 0)
+ return ccr;
+@@ -878,12 +881,14 @@ static int at803x_probe(struct phy_device *phydev)
+ break;
+ }
+
+- /* Disable WOL by default */
+- ret = at803x_set_wol(phydev, &wol);
+- if (ret < 0) {
+- phydev_err(phydev, "failed to disable WOL on probe: %d\n", ret);
++ /* Disable WoL in 1588 register which is enabled
++ * by default
++ */
++ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
++ AT803X_PHY_MMD3_WOL_CTRL,
++ AT803X_WOL_EN, 0);
++ if (ret)
+ return ret;
+- }
+ }
+
+ return 0;
+--
+2.40.1
+
--- /dev/null
+From 30a5242bf2eec19fbc2cc72f1c407b9aa8029890 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Jun 2023 16:24:37 +0200
+Subject: net: phy: at803x: Use devm_regulator_get_enable_optional()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 988e8d90b3dc482637532e61bc2d58bfc4af5167 ]
+
+Use devm_regulator_get_enable_optional() instead of hand writing it. It
+saves some line of code.
+
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: e58f30246c35 ("net: phy: at803x: fix the wol setting functions")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/at803x.c | 44 +++++++---------------------------------
+ 1 file changed, 7 insertions(+), 37 deletions(-)
+
+diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
+index 61824a463df85..e351fa8b84b7d 100644
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -305,7 +305,6 @@ struct at803x_priv {
+ bool is_1000basex;
+ struct regulator_dev *vddio_rdev;
+ struct regulator_dev *vddh_rdev;
+- struct regulator *vddio;
+ u64 stats[ARRAY_SIZE(at803x_hw_stats)];
+ };
+
+@@ -825,11 +824,11 @@ static int at803x_parse_dt(struct phy_device *phydev)
+ if (ret < 0)
+ return ret;
+
+- priv->vddio = devm_regulator_get_optional(&phydev->mdio.dev,
+- "vddio");
+- if (IS_ERR(priv->vddio)) {
++ ret = devm_regulator_get_enable_optional(&phydev->mdio.dev,
++ "vddio");
++ if (ret) {
+ phydev_err(phydev, "failed to get VDDIO regulator\n");
+- return PTR_ERR(priv->vddio);
++ return ret;
+ }
+
+ /* Only AR8031/8033 support 1000Base-X for SFP modules */
+@@ -857,12 +856,6 @@ static int at803x_probe(struct phy_device *phydev)
+ if (ret)
+ return ret;
+
+- if (priv->vddio) {
+- ret = regulator_enable(priv->vddio);
+- if (ret < 0)
+- return ret;
+- }
+-
+ if (phydev->drv->phy_id == ATH8031_PHY_ID) {
+ int ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
+ int mode_cfg;
+@@ -870,10 +863,8 @@ static int at803x_probe(struct phy_device *phydev)
+ .wolopts = 0,
+ };
+
+- if (ccr < 0) {
+- ret = ccr;
+- goto err;
+- }
++ if (ccr < 0)
++ return ccr;
+ mode_cfg = ccr & AT803X_MODE_CFG_MASK;
+
+ switch (mode_cfg) {
+@@ -891,25 +882,11 @@ static int at803x_probe(struct phy_device *phydev)
+ ret = at803x_set_wol(phydev, &wol);
+ if (ret < 0) {
+ phydev_err(phydev, "failed to disable WOL on probe: %d\n", ret);
+- goto err;
++ return ret;
+ }
+ }
+
+ return 0;
+-
+-err:
+- if (priv->vddio)
+- regulator_disable(priv->vddio);
+-
+- return ret;
+-}
+-
+-static void at803x_remove(struct phy_device *phydev)
+-{
+- struct at803x_priv *priv = phydev->priv;
+-
+- if (priv->vddio)
+- regulator_disable(priv->vddio);
+ }
+
+ static int at803x_get_features(struct phy_device *phydev)
+@@ -2022,7 +1999,6 @@ static struct phy_driver at803x_driver[] = {
+ .name = "Qualcomm Atheros AR8035",
+ .flags = PHY_POLL_CABLE_TEST,
+ .probe = at803x_probe,
+- .remove = at803x_remove,
+ .config_aneg = at803x_config_aneg,
+ .config_init = at803x_config_init,
+ .soft_reset = genphy_soft_reset,
+@@ -2044,7 +2020,6 @@ static struct phy_driver at803x_driver[] = {
+ .name = "Qualcomm Atheros AR8030",
+ .phy_id_mask = AT8030_PHY_ID_MASK,
+ .probe = at803x_probe,
+- .remove = at803x_remove,
+ .config_init = at803x_config_init,
+ .link_change_notify = at803x_link_change_notify,
+ .set_wol = at803x_set_wol,
+@@ -2060,7 +2035,6 @@ static struct phy_driver at803x_driver[] = {
+ .name = "Qualcomm Atheros AR8031/AR8033",
+ .flags = PHY_POLL_CABLE_TEST,
+ .probe = at803x_probe,
+- .remove = at803x_remove,
+ .config_init = at803x_config_init,
+ .config_aneg = at803x_config_aneg,
+ .soft_reset = genphy_soft_reset,
+@@ -2083,7 +2057,6 @@ static struct phy_driver at803x_driver[] = {
+ PHY_ID_MATCH_EXACT(ATH8032_PHY_ID),
+ .name = "Qualcomm Atheros AR8032",
+ .probe = at803x_probe,
+- .remove = at803x_remove,
+ .flags = PHY_POLL_CABLE_TEST,
+ .config_init = at803x_config_init,
+ .link_change_notify = at803x_link_change_notify,
+@@ -2099,7 +2072,6 @@ static struct phy_driver at803x_driver[] = {
+ PHY_ID_MATCH_EXACT(ATH9331_PHY_ID),
+ .name = "Qualcomm Atheros AR9331 built-in PHY",
+ .probe = at803x_probe,
+- .remove = at803x_remove,
+ .suspend = at803x_suspend,
+ .resume = at803x_resume,
+ .flags = PHY_POLL_CABLE_TEST,
+@@ -2116,7 +2088,6 @@ static struct phy_driver at803x_driver[] = {
+ PHY_ID_MATCH_EXACT(QCA9561_PHY_ID),
+ .name = "Qualcomm Atheros QCA9561 built-in PHY",
+ .probe = at803x_probe,
+- .remove = at803x_remove,
+ .suspend = at803x_suspend,
+ .resume = at803x_resume,
+ .flags = PHY_POLL_CABLE_TEST,
+@@ -2182,7 +2153,6 @@ static struct phy_driver at803x_driver[] = {
+ .name = "Qualcomm QCA8081",
+ .flags = PHY_POLL_CABLE_TEST,
+ .probe = at803x_probe,
+- .remove = at803x_remove,
+ .config_intr = at803x_config_intr,
+ .handle_interrupt = at803x_handle_interrupt,
+ .get_tunable = at803x_get_tunable,
+--
+2.40.1
+
--- /dev/null
+From bbe97904ee375c8f09349de3543a7e67c74d22cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 19:06:23 +0200
+Subject: net/smc: Fix setsockopt and sysctl to specify same buffer size again
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Gerd Bayer <gbayer@linux.ibm.com>
+
+[ Upstream commit 833bac7ec392bf75053c8a4fa4c36d4148dac77d ]
+
+Commit 0227f058aa29 ("net/smc: Unbind r/w buffer size from clcsock
+and make them tunable") introduced the net.smc.rmem and net.smc.wmem
+sysctls to specify the size of buffers to be used for SMC type
+connections. This created a regression for users that specified the
+buffer size via setsockopt() as the effective buffer size was now
+doubled.
+
+Re-introduce the division by 2 in the SMC buffer create code and level
+this out by duplicating the net.smc.[rw]mem values used for initializing
+sk_rcvbuf/sk_sndbuf at socket creation time. This gives users of both
+methods (setsockopt or sysctl) the effective buffer size that they
+expect.
+
+Initialize net.smc.[rw]mem from its own constant of 64kB, respectively.
+Internal performance tests show that this value is a good compromise
+between throughput/latency and memory consumption. Also, this decouples
+it from any tuning that was done to net.ipv4.tcp_[rw]mem[1] before the
+module for SMC protocol was loaded. Check that no more than INT_MAX / 2
+is assigned to net.smc.[rw]mem, in order to avoid any overflow condition
+when that is doubled for use in sk_sndbuf or sk_rcvbuf.
+
+While at it, drop the confusing sk_buf_size variable from
+__smc_buf_create and name "compressed" buffer size variables more
+consistently.
+
+Background:
+
+Before the commit mentioned above, SMC's buffer allocator in
+__smc_buf_create() always used half of the sockets' sk_rcvbuf/sk_sndbuf
+value as initial value to search for appropriate buffers. If the search
+resorted to using a bigger buffer when all buffers of the specified
+size were busy, the duplicate of the used effective buffer size is
+stored back to sk_rcvbuf/sk_sndbuf.
+
+When available, buffers of exactly the size that a user had specified as
+input to setsockopt() were used, despite setsockopt()'s documentation in
+"man 7 socket" talking of a mandatory duplication:
+
+[...]
+ SO_SNDBUF
+ Sets or gets the maximum socket send buffer in bytes.
+ The kernel doubles this value (to allow space for book‐
+ keeping overhead) when it is set using setsockopt(2),
+ and this doubled value is returned by getsockopt(2).
+ The default value is set by the
+ /proc/sys/net/core/wmem_default file and the maximum
+ allowed value is set by the /proc/sys/net/core/wmem_max
+ file. The minimum (doubled) value for this option is
+ 2048.
+[...]
+
+Fixes: 0227f058aa29 ("net/smc: Unbind r/w buffer size from clcsock and make them tunable")
+Co-developed-by: Jan Karcher <jaka@linux.ibm.com>
+Signed-off-by: Jan Karcher <jaka@linux.ibm.com>
+Reviewed-by: Wenjia Zhang <wenjia@linux.ibm.com>
+Reviewed-by: Tony Lu <tonylu@linux.alibaba.com>
+Signed-off-by: Gerd Bayer <gbayer@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/af_smc.c | 4 ++--
+ net/smc/smc.h | 2 +-
+ net/smc/smc_clc.c | 4 ++--
+ net/smc/smc_core.c | 25 ++++++++++++-------------
+ net/smc/smc_sysctl.c | 10 ++++++++--
+ 5 files changed, 25 insertions(+), 20 deletions(-)
+
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index 5712a5297bd01..84219c5121bc2 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -379,8 +379,8 @@ static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
+ sk->sk_state = SMC_INIT;
+ sk->sk_destruct = smc_destruct;
+ sk->sk_protocol = protocol;
+- WRITE_ONCE(sk->sk_sndbuf, READ_ONCE(net->smc.sysctl_wmem));
+- WRITE_ONCE(sk->sk_rcvbuf, READ_ONCE(net->smc.sysctl_rmem));
++ WRITE_ONCE(sk->sk_sndbuf, 2 * READ_ONCE(net->smc.sysctl_wmem));
++ WRITE_ONCE(sk->sk_rcvbuf, 2 * READ_ONCE(net->smc.sysctl_rmem));
+ smc = smc_sk(sk);
+ INIT_WORK(&smc->tcp_listen_work, smc_tcp_listen_work);
+ INIT_WORK(&smc->connect_work, smc_connect_work);
+diff --git a/net/smc/smc.h b/net/smc/smc.h
+index 5ed765ea0c731..1d36720fc019c 100644
+--- a/net/smc/smc.h
++++ b/net/smc/smc.h
+@@ -161,7 +161,7 @@ struct smc_connection {
+
+ struct smc_buf_desc *sndbuf_desc; /* send buffer descriptor */
+ struct smc_buf_desc *rmb_desc; /* RMBE descriptor */
+- int rmbe_size_short;/* compressed notation */
++ int rmbe_size_comp; /* compressed notation */
+ int rmbe_update_limit;
+ /* lower limit for consumer
+ * cursor update
+diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c
+index dfb9797f7bc63..9b8999e2afca5 100644
+--- a/net/smc/smc_clc.c
++++ b/net/smc/smc_clc.c
+@@ -1002,7 +1002,7 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
+ clc->hdr.typev1 = SMC_TYPE_D;
+ clc->d0.gid = conn->lgr->smcd->local_gid;
+ clc->d0.token = conn->rmb_desc->token;
+- clc->d0.dmbe_size = conn->rmbe_size_short;
++ clc->d0.dmbe_size = conn->rmbe_size_comp;
+ clc->d0.dmbe_idx = 0;
+ memcpy(&clc->d0.linkid, conn->lgr->id, SMC_LGR_ID_SIZE);
+ if (version == SMC_V1) {
+@@ -1045,7 +1045,7 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
+ clc->r0.qp_mtu = min(link->path_mtu, link->peer_mtu);
+ break;
+ }
+- clc->r0.rmbe_size = conn->rmbe_size_short;
++ clc->r0.rmbe_size = conn->rmbe_size_comp;
+ clc->r0.rmb_dma_addr = conn->rmb_desc->is_vm ?
+ cpu_to_be64((uintptr_t)conn->rmb_desc->cpu_addr) :
+ cpu_to_be64((u64)sg_dma_address
+diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
+index f793101e0ecc3..c676d92af7b7d 100644
+--- a/net/smc/smc_core.c
++++ b/net/smc/smc_core.c
+@@ -2305,31 +2305,30 @@ static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb)
+ struct smc_connection *conn = &smc->conn;
+ struct smc_link_group *lgr = conn->lgr;
+ struct list_head *buf_list;
+- int bufsize, bufsize_short;
++ int bufsize, bufsize_comp;
+ struct rw_semaphore *lock; /* lock buffer list */
+ bool is_dgraded = false;
+- int sk_buf_size;
+
+ if (is_rmb)
+ /* use socket recv buffer size (w/o overhead) as start value */
+- sk_buf_size = smc->sk.sk_rcvbuf;
++ bufsize = smc->sk.sk_rcvbuf / 2;
+ else
+ /* use socket send buffer size (w/o overhead) as start value */
+- sk_buf_size = smc->sk.sk_sndbuf;
++ bufsize = smc->sk.sk_sndbuf / 2;
+
+- for (bufsize_short = smc_compress_bufsize(sk_buf_size, is_smcd, is_rmb);
+- bufsize_short >= 0; bufsize_short--) {
++ for (bufsize_comp = smc_compress_bufsize(bufsize, is_smcd, is_rmb);
++ bufsize_comp >= 0; bufsize_comp--) {
+ if (is_rmb) {
+ lock = &lgr->rmbs_lock;
+- buf_list = &lgr->rmbs[bufsize_short];
++ buf_list = &lgr->rmbs[bufsize_comp];
+ } else {
+ lock = &lgr->sndbufs_lock;
+- buf_list = &lgr->sndbufs[bufsize_short];
++ buf_list = &lgr->sndbufs[bufsize_comp];
+ }
+- bufsize = smc_uncompress_bufsize(bufsize_short);
++ bufsize = smc_uncompress_bufsize(bufsize_comp);
+
+ /* check for reusable slot in the link group */
+- buf_desc = smc_buf_get_slot(bufsize_short, lock, buf_list);
++ buf_desc = smc_buf_get_slot(bufsize_comp, lock, buf_list);
+ if (buf_desc) {
+ buf_desc->is_dma_need_sync = 0;
+ SMC_STAT_RMB_SIZE(smc, is_smcd, is_rmb, bufsize);
+@@ -2373,8 +2372,8 @@ static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb)
+
+ if (is_rmb) {
+ conn->rmb_desc = buf_desc;
+- conn->rmbe_size_short = bufsize_short;
+- smc->sk.sk_rcvbuf = bufsize;
++ conn->rmbe_size_comp = bufsize_comp;
++ smc->sk.sk_rcvbuf = bufsize * 2;
+ atomic_set(&conn->bytes_to_rcv, 0);
+ conn->rmbe_update_limit =
+ smc_rmb_wnd_update_limit(buf_desc->len);
+@@ -2382,7 +2381,7 @@ static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb)
+ smc_ism_set_conn(conn); /* map RMB/smcd_dev to conn */
+ } else {
+ conn->sndbuf_desc = buf_desc;
+- smc->sk.sk_sndbuf = bufsize;
++ smc->sk.sk_sndbuf = bufsize * 2;
+ atomic_set(&conn->sndbuf_space, bufsize);
+ }
+ return 0;
+diff --git a/net/smc/smc_sysctl.c b/net/smc/smc_sysctl.c
+index b6f79fabb9d3f..0b2a957ca5f5f 100644
+--- a/net/smc/smc_sysctl.c
++++ b/net/smc/smc_sysctl.c
+@@ -21,6 +21,10 @@
+
+ static int min_sndbuf = SMC_BUF_MIN_SIZE;
+ static int min_rcvbuf = SMC_BUF_MIN_SIZE;
++static int max_sndbuf = INT_MAX / 2;
++static int max_rcvbuf = INT_MAX / 2;
++static const int net_smc_wmem_init = (64 * 1024);
++static const int net_smc_rmem_init = (64 * 1024);
+
+ static struct ctl_table smc_table[] = {
+ {
+@@ -53,6 +57,7 @@ static struct ctl_table smc_table[] = {
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &min_sndbuf,
++ .extra2 = &max_sndbuf,
+ },
+ {
+ .procname = "rmem",
+@@ -61,6 +66,7 @@ static struct ctl_table smc_table[] = {
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &min_rcvbuf,
++ .extra2 = &max_rcvbuf,
+ },
+ { }
+ };
+@@ -88,8 +94,8 @@ int __net_init smc_sysctl_net_init(struct net *net)
+ net->smc.sysctl_autocorking_size = SMC_AUTOCORKING_DEFAULT_SIZE;
+ net->smc.sysctl_smcr_buf_type = SMCR_PHYS_CONT_BUFS;
+ net->smc.sysctl_smcr_testlink_time = SMC_LLC_TESTLINK_DEFAULT_TIME;
+- WRITE_ONCE(net->smc.sysctl_wmem, READ_ONCE(net->ipv4.sysctl_tcp_wmem[1]));
+- WRITE_ONCE(net->smc.sysctl_rmem, READ_ONCE(net->ipv4.sysctl_tcp_rmem[1]));
++ WRITE_ONCE(net->smc.sysctl_wmem, net_smc_wmem_init);
++ WRITE_ONCE(net->smc.sysctl_rmem, net_smc_rmem_init);
+
+ return 0;
+
+--
+2.40.1
+
--- /dev/null
+From 6964a4b3d2eb581630132c568dfc433d562e3ac4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 16:26:42 +0800
+Subject: net/smc: replace mutex rmbs_lock and sndbufs_lock with rw_semaphore
+
+From: D. Wythe <alibuda@linux.alibaba.com>
+
+[ Upstream commit aff7bfed9097435ea38de919befbe2d7771a3e87 ]
+
+It's clear that rmbs_lock and sndbufs_lock are aims to protect the
+rmbs list or the sndbufs list.
+
+During connection establieshment, smc_buf_get_slot() will always
+be invoked, and it only performs read semantics in rmbs list and
+sndbufs list.
+
+Based on the above considerations, we replace mutex with rw_semaphore.
+Only smc_buf_get_slot() use down_read() to allow smc_buf_get_slot()
+run concurrently, other part use down_write() to keep exclusive
+semantics.
+
+Signed-off-by: D. Wythe <alibuda@linux.alibaba.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 833bac7ec392 ("net/smc: Fix setsockopt and sysctl to specify same buffer size again")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/smc_core.c | 55 +++++++++++++++++++++++-----------------------
+ net/smc/smc_core.h | 4 ++--
+ net/smc/smc_llc.c | 16 +++++++-------
+ 3 files changed, 38 insertions(+), 37 deletions(-)
+
+diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
+index f82f43573a159..f793101e0ecc3 100644
+--- a/net/smc/smc_core.c
++++ b/net/smc/smc_core.c
+@@ -852,8 +852,8 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
+ lgr->freeing = 0;
+ lgr->vlan_id = ini->vlan_id;
+ refcount_set(&lgr->refcnt, 1); /* set lgr refcnt to 1 */
+- mutex_init(&lgr->sndbufs_lock);
+- mutex_init(&lgr->rmbs_lock);
++ init_rwsem(&lgr->sndbufs_lock);
++ init_rwsem(&lgr->rmbs_lock);
+ rwlock_init(&lgr->conns_lock);
+ for (i = 0; i < SMC_RMBE_SIZES; i++) {
+ INIT_LIST_HEAD(&lgr->sndbufs[i]);
+@@ -1095,7 +1095,7 @@ struct smc_link *smc_switch_conns(struct smc_link_group *lgr,
+ static void smcr_buf_unuse(struct smc_buf_desc *buf_desc, bool is_rmb,
+ struct smc_link_group *lgr)
+ {
+- struct mutex *lock; /* lock buffer list */
++ struct rw_semaphore *lock; /* lock buffer list */
+ int rc;
+
+ if (is_rmb && buf_desc->is_conf_rkey && !list_empty(&lgr->list)) {
+@@ -1115,9 +1115,9 @@ static void smcr_buf_unuse(struct smc_buf_desc *buf_desc, bool is_rmb,
+ /* buf registration failed, reuse not possible */
+ lock = is_rmb ? &lgr->rmbs_lock :
+ &lgr->sndbufs_lock;
+- mutex_lock(lock);
++ down_write(lock);
+ list_del(&buf_desc->list);
+- mutex_unlock(lock);
++ up_write(lock);
+
+ smc_buf_free(lgr, is_rmb, buf_desc);
+ } else {
+@@ -1220,15 +1220,16 @@ static void smcr_buf_unmap_lgr(struct smc_link *lnk)
+ int i;
+
+ for (i = 0; i < SMC_RMBE_SIZES; i++) {
+- mutex_lock(&lgr->rmbs_lock);
++ down_write(&lgr->rmbs_lock);
+ list_for_each_entry_safe(buf_desc, bf, &lgr->rmbs[i], list)
+ smcr_buf_unmap_link(buf_desc, true, lnk);
+- mutex_unlock(&lgr->rmbs_lock);
+- mutex_lock(&lgr->sndbufs_lock);
++ up_write(&lgr->rmbs_lock);
++
++ down_write(&lgr->sndbufs_lock);
+ list_for_each_entry_safe(buf_desc, bf, &lgr->sndbufs[i],
+ list)
+ smcr_buf_unmap_link(buf_desc, false, lnk);
+- mutex_unlock(&lgr->sndbufs_lock);
++ up_write(&lgr->sndbufs_lock);
+ }
+ }
+
+@@ -1986,19 +1987,19 @@ int smc_uncompress_bufsize(u8 compressed)
+ * buffer size; if not available, return NULL
+ */
+ static struct smc_buf_desc *smc_buf_get_slot(int compressed_bufsize,
+- struct mutex *lock,
++ struct rw_semaphore *lock,
+ struct list_head *buf_list)
+ {
+ struct smc_buf_desc *buf_slot;
+
+- mutex_lock(lock);
++ down_read(lock);
+ list_for_each_entry(buf_slot, buf_list, list) {
+ if (cmpxchg(&buf_slot->used, 0, 1) == 0) {
+- mutex_unlock(lock);
++ up_read(lock);
+ return buf_slot;
+ }
+ }
+- mutex_unlock(lock);
++ up_read(lock);
+ return NULL;
+ }
+
+@@ -2107,13 +2108,13 @@ int smcr_link_reg_buf(struct smc_link *link, struct smc_buf_desc *buf_desc)
+ return 0;
+ }
+
+-static int _smcr_buf_map_lgr(struct smc_link *lnk, struct mutex *lock,
++static int _smcr_buf_map_lgr(struct smc_link *lnk, struct rw_semaphore *lock,
+ struct list_head *lst, bool is_rmb)
+ {
+ struct smc_buf_desc *buf_desc, *bf;
+ int rc = 0;
+
+- mutex_lock(lock);
++ down_write(lock);
+ list_for_each_entry_safe(buf_desc, bf, lst, list) {
+ if (!buf_desc->used)
+ continue;
+@@ -2122,7 +2123,7 @@ static int _smcr_buf_map_lgr(struct smc_link *lnk, struct mutex *lock,
+ goto out;
+ }
+ out:
+- mutex_unlock(lock);
++ up_write(lock);
+ return rc;
+ }
+
+@@ -2155,37 +2156,37 @@ int smcr_buf_reg_lgr(struct smc_link *lnk)
+ int i, rc = 0;
+
+ /* reg all RMBs for a new link */
+- mutex_lock(&lgr->rmbs_lock);
++ down_write(&lgr->rmbs_lock);
+ for (i = 0; i < SMC_RMBE_SIZES; i++) {
+ list_for_each_entry_safe(buf_desc, bf, &lgr->rmbs[i], list) {
+ if (!buf_desc->used)
+ continue;
+ rc = smcr_link_reg_buf(lnk, buf_desc);
+ if (rc) {
+- mutex_unlock(&lgr->rmbs_lock);
++ up_write(&lgr->rmbs_lock);
+ return rc;
+ }
+ }
+ }
+- mutex_unlock(&lgr->rmbs_lock);
++ up_write(&lgr->rmbs_lock);
+
+ if (lgr->buf_type == SMCR_PHYS_CONT_BUFS)
+ return rc;
+
+ /* reg all vzalloced sndbufs for a new link */
+- mutex_lock(&lgr->sndbufs_lock);
++ down_write(&lgr->sndbufs_lock);
+ for (i = 0; i < SMC_RMBE_SIZES; i++) {
+ list_for_each_entry_safe(buf_desc, bf, &lgr->sndbufs[i], list) {
+ if (!buf_desc->used || !buf_desc->is_vm)
+ continue;
+ rc = smcr_link_reg_buf(lnk, buf_desc);
+ if (rc) {
+- mutex_unlock(&lgr->sndbufs_lock);
++ up_write(&lgr->sndbufs_lock);
+ return rc;
+ }
+ }
+ }
+- mutex_unlock(&lgr->sndbufs_lock);
++ up_write(&lgr->sndbufs_lock);
+ return rc;
+ }
+
+@@ -2305,8 +2306,8 @@ static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb)
+ struct smc_link_group *lgr = conn->lgr;
+ struct list_head *buf_list;
+ int bufsize, bufsize_short;
++ struct rw_semaphore *lock; /* lock buffer list */
+ bool is_dgraded = false;
+- struct mutex *lock; /* lock buffer list */
+ int sk_buf_size;
+
+ if (is_rmb)
+@@ -2354,9 +2355,9 @@ static int __smc_buf_create(struct smc_sock *smc, bool is_smcd, bool is_rmb)
+ SMC_STAT_RMB_ALLOC(smc, is_smcd, is_rmb);
+ SMC_STAT_RMB_SIZE(smc, is_smcd, is_rmb, bufsize);
+ buf_desc->used = 1;
+- mutex_lock(lock);
++ down_write(lock);
+ list_add(&buf_desc->list, buf_list);
+- mutex_unlock(lock);
++ up_write(lock);
+ break; /* found */
+ }
+
+@@ -2430,9 +2431,9 @@ int smc_buf_create(struct smc_sock *smc, bool is_smcd)
+ /* create rmb */
+ rc = __smc_buf_create(smc, is_smcd, true);
+ if (rc) {
+- mutex_lock(&smc->conn.lgr->sndbufs_lock);
++ down_write(&smc->conn.lgr->sndbufs_lock);
+ list_del(&smc->conn.sndbuf_desc->list);
+- mutex_unlock(&smc->conn.lgr->sndbufs_lock);
++ up_write(&smc->conn.lgr->sndbufs_lock);
+ smc_buf_free(smc->conn.lgr, false, smc->conn.sndbuf_desc);
+ smc->conn.sndbuf_desc = NULL;
+ }
+diff --git a/net/smc/smc_core.h b/net/smc/smc_core.h
+index 285f9bd8e232e..6051d92270130 100644
+--- a/net/smc/smc_core.h
++++ b/net/smc/smc_core.h
+@@ -252,9 +252,9 @@ struct smc_link_group {
+ unsigned short vlan_id; /* vlan id of link group */
+
+ struct list_head sndbufs[SMC_RMBE_SIZES];/* tx buffers */
+- struct mutex sndbufs_lock; /* protects tx buffers */
++ struct rw_semaphore sndbufs_lock; /* protects tx buffers */
+ struct list_head rmbs[SMC_RMBE_SIZES]; /* rx buffers */
+- struct mutex rmbs_lock; /* protects rx buffers */
++ struct rw_semaphore rmbs_lock; /* protects rx buffers */
+
+ u8 id[SMC_LGR_ID_SIZE]; /* unique lgr id */
+ struct delayed_work free_work; /* delayed freeing of an lgr */
+diff --git a/net/smc/smc_llc.c b/net/smc/smc_llc.c
+index 760f8bbff822e..fcb24a0ccf761 100644
+--- a/net/smc/smc_llc.c
++++ b/net/smc/smc_llc.c
+@@ -611,7 +611,7 @@ static int smc_llc_fill_ext_v2(struct smc_llc_msg_add_link_v2_ext *ext,
+
+ prim_lnk_idx = link->link_idx;
+ lnk_idx = link_new->link_idx;
+- mutex_lock(&lgr->rmbs_lock);
++ down_write(&lgr->rmbs_lock);
+ ext->num_rkeys = lgr->conns_num;
+ if (!ext->num_rkeys)
+ goto out;
+@@ -631,7 +631,7 @@ static int smc_llc_fill_ext_v2(struct smc_llc_msg_add_link_v2_ext *ext,
+ }
+ len += i * sizeof(ext->rt[0]);
+ out:
+- mutex_unlock(&lgr->rmbs_lock);
++ up_write(&lgr->rmbs_lock);
+ return len;
+ }
+
+@@ -892,7 +892,7 @@ static int smc_llc_cli_rkey_exchange(struct smc_link *link,
+ int rc = 0;
+ int i;
+
+- mutex_lock(&lgr->rmbs_lock);
++ down_write(&lgr->rmbs_lock);
+ num_rkeys_send = lgr->conns_num;
+ buf_pos = smc_llc_get_first_rmb(lgr, &buf_lst);
+ do {
+@@ -919,7 +919,7 @@ static int smc_llc_cli_rkey_exchange(struct smc_link *link,
+ break;
+ } while (num_rkeys_send || num_rkeys_recv);
+
+- mutex_unlock(&lgr->rmbs_lock);
++ up_write(&lgr->rmbs_lock);
+ return rc;
+ }
+
+@@ -1002,14 +1002,14 @@ static void smc_llc_save_add_link_rkeys(struct smc_link *link,
+ ext = (struct smc_llc_msg_add_link_v2_ext *)((u8 *)lgr->wr_rx_buf_v2 +
+ SMC_WR_TX_SIZE);
+ max = min_t(u8, ext->num_rkeys, SMC_LLC_RKEYS_PER_MSG_V2);
+- mutex_lock(&lgr->rmbs_lock);
++ down_write(&lgr->rmbs_lock);
+ for (i = 0; i < max; i++) {
+ smc_rtoken_set(lgr, link->link_idx, link_new->link_idx,
+ ext->rt[i].rmb_key,
+ ext->rt[i].rmb_vaddr_new,
+ ext->rt[i].rmb_key_new);
+ }
+- mutex_unlock(&lgr->rmbs_lock);
++ up_write(&lgr->rmbs_lock);
+ }
+
+ static void smc_llc_save_add_link_info(struct smc_link *link,
+@@ -1316,7 +1316,7 @@ static int smc_llc_srv_rkey_exchange(struct smc_link *link,
+ int rc = 0;
+ int i;
+
+- mutex_lock(&lgr->rmbs_lock);
++ down_write(&lgr->rmbs_lock);
+ num_rkeys_send = lgr->conns_num;
+ buf_pos = smc_llc_get_first_rmb(lgr, &buf_lst);
+ do {
+@@ -1341,7 +1341,7 @@ static int smc_llc_srv_rkey_exchange(struct smc_link *link,
+ smc_llc_flow_qentry_del(&lgr->llc_flow_lcl);
+ } while (num_rkeys_send || num_rkeys_recv);
+ out:
+- mutex_unlock(&lgr->rmbs_lock);
++ up_write(&lgr->rmbs_lock);
+ return rc;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From d01f4cee237b3a0cba25055f9e083a53ec71afcd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 10:04:40 +0800
+Subject: nvme: core: don't hold rcu read lock in nvme_ns_chr_uring_cmd_iopoll
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit a7a7dabb5dd72d2875bc3ce56f94ea5ceb259d5b ]
+
+Now nvme_ns_chr_uring_cmd_iopoll() has switched to request based io
+polling, and the associated NS is guaranteed to be live in case of
+io polling, so request is guaranteed to be valid because blk-mq uses
+pre-allocated request pool.
+
+Remove the rcu read lock in nvme_ns_chr_uring_cmd_iopoll(), which
+isn't needed any more after switching to request based io polling.
+
+Fix "BUG: sleeping function called from invalid context" because
+set_page_dirty_lock() from blk_rq_unmap_user() may sleep.
+
+Fixes: 585079b6e425 ("nvme: wire up async polling for io passthrough commands")
+Reported-by: Guangwu Zhang <guazhang@redhat.com>
+Cc: Kanchan Joshi <joshi.k@samsung.com>
+Cc: Anuj Gupta <anuj20.g@samsung.com>
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Tested-by: Guangwu Zhang <guazhang@redhat.com>
+Link: https://lore.kernel.org/r/20230809020440.174682-1-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/ioctl.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
+index 8224675f8de25..ac7d61ce30108 100644
+--- a/drivers/nvme/host/ioctl.c
++++ b/drivers/nvme/host/ioctl.c
+@@ -706,14 +706,12 @@ int nvme_ns_chr_uring_cmd_iopoll(struct io_uring_cmd *ioucmd,
+ struct nvme_ns *ns;
+ struct request_queue *q;
+
+- rcu_read_lock();
+ bio = READ_ONCE(ioucmd->cookie);
+ ns = container_of(file_inode(ioucmd->file)->i_cdev,
+ struct nvme_ns, cdev);
+ q = ns->queue;
+ if (test_bit(QUEUE_FLAG_POLL, &q->queue_flags) && bio && bio->bi_bdev)
+ ret = bio_poll(bio, iob, poll_flags);
+- rcu_read_unlock();
+ return ret;
+ }
+ #ifdef CONFIG_NVME_MULTIPATH
+--
+2.40.1
+
--- /dev/null
+From 183fa0699e7c350e3ff20ccd1965ff49cf8e0879 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 May 2023 23:02:09 +0530
+Subject: PCI: tegra194: Fix possible array out of bounds access
+
+From: Sumit Gupta <sumitg@nvidia.com>
+
+[ Upstream commit 205b3d02d57ce6dce96f6d2b9c230f56a9bf9817 ]
+
+Add check to fix the possible array out of bounds violation by
+making speed equal to GEN1_CORE_CLK_FREQ when its value is more
+than the size of "pcie_gen_freq" array. This array has size of
+four but possible speed (CLS) values are from "0 to 0xF". So,
+"speed - 1" values are "-1 to 0xE".
+
+Suggested-by: Bjorn Helgaas <helgaas@kernel.org>
+Signed-off-by: Sumit Gupta <sumitg@nvidia.com>
+Link: https://lore.kernel.org/lkml/72b9168b-d4d6-4312-32ea-69358df2f2d0@nvidia.com/
+Acked-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-tegra194.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
+index 1b6b437823d22..528e73ccfa43e 100644
+--- a/drivers/pci/controller/dwc/pcie-tegra194.c
++++ b/drivers/pci/controller/dwc/pcie-tegra194.c
+@@ -224,6 +224,7 @@
+ #define EP_STATE_ENABLED 1
+
+ static const unsigned int pcie_gen_freq[] = {
++ GEN1_CORE_CLK_FREQ, /* PCI_EXP_LNKSTA_CLS == 0; undefined */
+ GEN1_CORE_CLK_FREQ,
+ GEN2_CORE_CLK_FREQ,
+ GEN3_CORE_CLK_FREQ,
+@@ -455,7 +456,11 @@ static irqreturn_t tegra_pcie_ep_irq_thread(int irq, void *arg)
+
+ speed = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA) &
+ PCI_EXP_LNKSTA_CLS;
+- clk_set_rate(pcie->core_clk, pcie_gen_freq[speed - 1]);
++
++ if (speed >= ARRAY_SIZE(pcie_gen_freq))
++ speed = 0;
++
++ clk_set_rate(pcie->core_clk, pcie_gen_freq[speed]);
+
+ if (pcie->of_data->has_ltr_req_fix)
+ return IRQ_HANDLED;
+@@ -1016,7 +1021,11 @@ static int tegra_pcie_dw_start_link(struct dw_pcie *pci)
+
+ speed = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA) &
+ PCI_EXP_LNKSTA_CLS;
+- clk_set_rate(pcie->core_clk, pcie_gen_freq[speed - 1]);
++
++ if (speed >= ARRAY_SIZE(pcie_gen_freq))
++ speed = 0;
++
++ clk_set_rate(pcie->core_clk, pcie_gen_freq[speed]);
+
+ tegra_pcie_enable_interrupts(pp);
+
+--
+2.40.1
+
--- /dev/null
+From 8fd6bd43bb01727a9f87331a131675ac230c80e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 May 2023 20:45:29 +0200
+Subject: pcmcia: rsrc_nonstatic: Fix memory leak in
+ nonstatic_release_resource_db()
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+[ Upstream commit c85fd9422fe0f5d667305efb27f56d09eab120b0 ]
+
+When nonstatic_release_resource_db() frees all resources associated
+with an PCMCIA socket, it forgets to free socket_data too, causing
+a memory leak observable with kmemleak:
+
+unreferenced object 0xc28d1000 (size 64):
+ comm "systemd-udevd", pid 297, jiffies 4294898478 (age 194.484s)
+ hex dump (first 32 bytes):
+ 00 00 00 00 00 00 00 00 f0 85 0e c3 00 00 00 00 ................
+ 00 00 00 00 0c 10 8d c2 00 00 00 00 00 00 00 00 ................
+ backtrace:
+ [<ffda4245>] __kmem_cache_alloc_node+0x2d7/0x4a0
+ [<7e51f0c8>] kmalloc_trace+0x31/0xa4
+ [<d52b4ca0>] nonstatic_init+0x24/0x1a4 [pcmcia_rsrc]
+ [<a2f13e08>] pcmcia_register_socket+0x200/0x35c [pcmcia_core]
+ [<a728be1b>] yenta_probe+0x4d8/0xa70 [yenta_socket]
+ [<c48fac39>] pci_device_probe+0x99/0x194
+ [<84b7c690>] really_probe+0x181/0x45c
+ [<8060fe6e>] __driver_probe_device+0x75/0x1f4
+ [<b9b76f43>] driver_probe_device+0x28/0xac
+ [<648b766f>] __driver_attach+0xeb/0x1e4
+ [<6e9659eb>] bus_for_each_dev+0x61/0xb4
+ [<25a669f3>] driver_attach+0x1e/0x28
+ [<d8671d6b>] bus_add_driver+0x102/0x20c
+ [<df0d323c>] driver_register+0x5b/0x120
+ [<942cd8a4>] __pci_register_driver+0x44/0x4c
+ [<e536027e>] __UNIQUE_ID___addressable_cleanup_module188+0x1c/0xfffff000 [iTCO_vendor_support]
+
+Fix this by freeing socket_data too.
+
+Tested on a Acer Travelmate 4002WLMi by manually binding/unbinding
+the yenta_cardbus driver (yenta_socket).
+
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Message-ID: <20230512184529.5094-1-W_Armin@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pcmcia/rsrc_nonstatic.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
+index ad1141fddb4cc..8bda75990bce5 100644
+--- a/drivers/pcmcia/rsrc_nonstatic.c
++++ b/drivers/pcmcia/rsrc_nonstatic.c
+@@ -1053,6 +1053,8 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
+ q = p->next;
+ kfree(p);
+ }
++
++ kfree(data);
+ }
+
+
+--
+2.40.1
+
--- /dev/null
+From 1ab565108616e5246cb2505fca6e9348a712bc33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Jul 2023 14:41:43 +1000
+Subject: powerpc/kasan: Disable KCOV in KASAN code
+
+From: Benjamin Gray <bgray@linux.ibm.com>
+
+[ Upstream commit ccb381e1af1ace292153c88eb1fffa5683d16a20 ]
+
+As per the generic KASAN code in mm/kasan, disable KCOV with
+KCOV_INSTRUMENT := n in the makefile.
+
+This fixes a ppc64 boot hang when KCOV and KASAN are enabled.
+kasan_early_init() gets called before a PACA is initialised, but the
+KCOV hook expects a valid PACA.
+
+Suggested-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Benjamin Gray <bgray@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20230710044143.146840-1-bgray@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/mm/kasan/Makefile | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/powerpc/mm/kasan/Makefile b/arch/powerpc/mm/kasan/Makefile
+index 699eeffd9f551..f9522fd70b2f3 100644
+--- a/arch/powerpc/mm/kasan/Makefile
++++ b/arch/powerpc/mm/kasan/Makefile
+@@ -1,6 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+
+ KASAN_SANITIZE := n
++KCOV_INSTRUMENT := n
+
+ obj-$(CONFIG_PPC32) += init_32.o
+ obj-$(CONFIG_PPC_8xx) += 8xx.o
+--
+2.40.1
+
--- /dev/null
+From e9b3c4d2334cb08ecf06ad61f998e75ca2792667 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Jun 2023 13:14:07 +0300
+Subject: RDMA/mlx5: Return the firmware result upon destroying QP/RQ
+
+From: Patrisious Haddad <phaddad@nvidia.com>
+
+[ Upstream commit 22664c06e997087fe37f9ba208008c948571214a ]
+
+Previously when destroying a QP/RQ, the result of the firmware
+destruction function was ignored and upper layers weren't informed
+about the failure.
+Which in turn could lead to various problems since when upper layer
+isn't aware of the failure it continues its operation thinking that the
+related QP/RQ was successfully destroyed while it actually wasn't,
+which could lead to the below kernel WARN.
+
+Currently, we return the correct firmware destruction status to upper
+layers which in case of the RQ would be mlx5_ib_destroy_wq() which
+was already capable of handling RQ destruction failure or in case of
+a QP to destroy_qp_common(), which now would actually warn upon qp
+destruction failure.
+
+WARNING: CPU: 3 PID: 995 at drivers/infiniband/core/rdma_core.c:940 uverbs_destroy_ufile_hw+0xcb/0xe0 [ib_uverbs]
+Modules linked in: xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink xt_addrtype iptable_nat nf_nat br_netfilter rpcrdma rdma_ucm ib_iser libiscsi scsi_transport_iscsi rdma_cm ib_umad ib_ipoib iw_cm ib_cm mlx5_ib ib_uverbs ib_core overlay mlx5_core fuse
+CPU: 3 PID: 995 Comm: python3 Not tainted 5.16.0-rc5+ #1
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
+RIP: 0010:uverbs_destroy_ufile_hw+0xcb/0xe0 [ib_uverbs]
+Code: 41 5c 41 5d 41 5e e9 44 34 f0 e0 48 89 df e8 4c 77 ff ff 49 8b 86 10 01 00 00 48 85 c0 74 a1 4c 89 e7 ff d0 eb 9a 0f 0b eb c1 <0f> 0b be 04 00 00 00 48 89 df e8 b6 f6 ff ff e9 75 ff ff ff 90 0f
+RSP: 0018:ffff8881533e3e78 EFLAGS: 00010287
+RAX: ffff88811b2cf3e0 RBX: ffff888106209700 RCX: 0000000000000000
+RDX: ffff888106209780 RSI: ffff8881533e3d30 RDI: ffff888109b101a0
+RBP: 0000000000000001 R08: ffff888127cb381c R09: 0de9890000000009
+R10: ffff888127cb3800 R11: 0000000000000000 R12: ffff888106209780
+R13: ffff888106209750 R14: ffff888100f20660 R15: 0000000000000000
+FS: 00007f8be353b740(0000) GS:ffff88852c980000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f8bd5b117c0 CR3: 000000012cd8a004 CR4: 0000000000370ea0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ <TASK>
+ ib_uverbs_close+0x1a/0x90 [ib_uverbs]
+ __fput+0x82/0x230
+ task_work_run+0x59/0x90
+ exit_to_user_mode_prepare+0x138/0x140
+ syscall_exit_to_user_mode+0x1d/0x50
+ ? __x64_sys_close+0xe/0x40
+ do_syscall_64+0x4a/0x90
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+RIP: 0033:0x7f8be3ae0abb
+Code: 03 00 00 00 0f 05 48 3d 00 f0 ff ff 77 41 c3 48 83 ec 18 89 7c 24 0c e8 83 43 f9 ff 8b 7c 24 0c 41 89 c0 b8 03 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 35 44 89 c7 89 44 24 0c e8 c1 43 f9 ff 8b 44
+RSP: 002b:00007ffdb51909c0 EFLAGS: 00000293 ORIG_RAX: 0000000000000003
+RAX: 0000000000000000 RBX: 0000557bb7f7c020 RCX: 00007f8be3ae0abb
+RDX: 0000557bb7c74010 RSI: 0000557bb7f14ca0 RDI: 0000000000000005
+RBP: 0000557bb7fbd598 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000293 R12: 0000557bb7fbd5b8
+R13: 0000557bb7fbd5a8 R14: 0000000000001000 R15: 0000557bb7f7c020
+ </TASK>
+
+Signed-off-by: Patrisious Haddad <phaddad@nvidia.com>
+Link: https://lore.kernel.org/r/c6df677f931d18090bafbe7f7dbb9524047b7d9b.1685953497.git.leon@kernel.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/qpc.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/qpc.c b/drivers/infiniband/hw/mlx5/qpc.c
+index 542e4c63a8de6..d4e7864c56f18 100644
+--- a/drivers/infiniband/hw/mlx5/qpc.c
++++ b/drivers/infiniband/hw/mlx5/qpc.c
+@@ -297,8 +297,7 @@ int mlx5_core_destroy_qp(struct mlx5_ib_dev *dev, struct mlx5_core_qp *qp)
+ MLX5_SET(destroy_qp_in, in, opcode, MLX5_CMD_OP_DESTROY_QP);
+ MLX5_SET(destroy_qp_in, in, qpn, qp->qpn);
+ MLX5_SET(destroy_qp_in, in, uid, qp->uid);
+- mlx5_cmd_exec_in(dev->mdev, destroy_qp, in);
+- return 0;
++ return mlx5_cmd_exec_in(dev->mdev, destroy_qp, in);
+ }
+
+ int mlx5_core_set_delay_drop(struct mlx5_ib_dev *dev,
+@@ -548,14 +547,14 @@ int mlx5_core_xrcd_dealloc(struct mlx5_ib_dev *dev, u32 xrcdn)
+ return mlx5_cmd_exec_in(dev->mdev, dealloc_xrcd, in);
+ }
+
+-static void destroy_rq_tracked(struct mlx5_ib_dev *dev, u32 rqn, u16 uid)
++static int destroy_rq_tracked(struct mlx5_ib_dev *dev, u32 rqn, u16 uid)
+ {
+ u32 in[MLX5_ST_SZ_DW(destroy_rq_in)] = {};
+
+ MLX5_SET(destroy_rq_in, in, opcode, MLX5_CMD_OP_DESTROY_RQ);
+ MLX5_SET(destroy_rq_in, in, rqn, rqn);
+ MLX5_SET(destroy_rq_in, in, uid, uid);
+- mlx5_cmd_exec_in(dev->mdev, destroy_rq, in);
++ return mlx5_cmd_exec_in(dev->mdev, destroy_rq, in);
+ }
+
+ int mlx5_core_create_rq_tracked(struct mlx5_ib_dev *dev, u32 *in, int inlen,
+@@ -586,8 +585,7 @@ int mlx5_core_destroy_rq_tracked(struct mlx5_ib_dev *dev,
+ struct mlx5_core_qp *rq)
+ {
+ destroy_resource_common(dev, rq);
+- destroy_rq_tracked(dev, rq->qpn, rq->uid);
+- return 0;
++ return destroy_rq_tracked(dev, rq->qpn, rq->uid);
+ }
+
+ static void destroy_sq_tracked(struct mlx5_ib_dev *dev, u32 sqn, u16 uid)
+--
+2.40.1
+
--- /dev/null
+From 580dada0669961d2faaeace4f27de722d024ac43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Jul 2023 15:58:47 +0800
+Subject: ring-buffer: Do not swap cpu_buffer during resize process
+
+From: Chen Lin <chen.lin5@zte.com.cn>
+
+[ Upstream commit 8a96c0288d0737ad77882024974c075345c72011 ]
+
+When ring_buffer_swap_cpu was called during resize process,
+the cpu buffer was swapped in the middle, resulting in incorrect state.
+Continuing to run in the wrong state will result in oops.
+
+This issue can be easily reproduced using the following two scripts:
+/tmp # cat test1.sh
+//#! /bin/sh
+for i in `seq 0 100000`
+do
+ echo 2000 > /sys/kernel/debug/tracing/buffer_size_kb
+ sleep 0.5
+ echo 5000 > /sys/kernel/debug/tracing/buffer_size_kb
+ sleep 0.5
+done
+/tmp # cat test2.sh
+//#! /bin/sh
+for i in `seq 0 100000`
+do
+ echo irqsoff > /sys/kernel/debug/tracing/current_tracer
+ sleep 1
+ echo nop > /sys/kernel/debug/tracing/current_tracer
+ sleep 1
+done
+/tmp # ./test1.sh &
+/tmp # ./test2.sh &
+
+A typical oops log is as follows, sometimes with other different oops logs.
+
+[ 231.711293] WARNING: CPU: 0 PID: 9 at kernel/trace/ring_buffer.c:2026 rb_update_pages+0x378/0x3f8
+[ 231.713375] Modules linked in:
+[ 231.714735] CPU: 0 PID: 9 Comm: kworker/0:1 Tainted: G W 6.5.0-rc1-00276-g20edcec23f92 #15
+[ 231.716750] Hardware name: linux,dummy-virt (DT)
+[ 231.718152] Workqueue: events update_pages_handler
+[ 231.719714] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+[ 231.721171] pc : rb_update_pages+0x378/0x3f8
+[ 231.722212] lr : rb_update_pages+0x25c/0x3f8
+[ 231.723248] sp : ffff800082b9bd50
+[ 231.724169] x29: ffff800082b9bd50 x28: ffff8000825f7000 x27: 0000000000000000
+[ 231.726102] x26: 0000000000000001 x25: fffffffffffff010 x24: 0000000000000ff0
+[ 231.728122] x23: ffff0000c3a0b600 x22: ffff0000c3a0b5c0 x21: fffffffffffffe0a
+[ 231.730203] x20: ffff0000c3a0b600 x19: ffff0000c0102400 x18: 0000000000000000
+[ 231.732329] x17: 0000000000000000 x16: 0000000000000000 x15: 0000ffffe7aa8510
+[ 231.734212] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000002
+[ 231.736291] x11: ffff8000826998a8 x10: ffff800082b9baf0 x9 : ffff800081137558
+[ 231.738195] x8 : fffffc00030e82c8 x7 : 0000000000000000 x6 : 0000000000000001
+[ 231.740192] x5 : ffff0000ffbafe00 x4 : 0000000000000000 x3 : 0000000000000000
+[ 231.742118] x2 : 00000000000006aa x1 : 0000000000000001 x0 : ffff0000c0007208
+[ 231.744196] Call trace:
+[ 231.744892] rb_update_pages+0x378/0x3f8
+[ 231.745893] update_pages_handler+0x1c/0x38
+[ 231.746893] process_one_work+0x1f0/0x468
+[ 231.747852] worker_thread+0x54/0x410
+[ 231.748737] kthread+0x124/0x138
+[ 231.749549] ret_from_fork+0x10/0x20
+[ 231.750434] ---[ end trace 0000000000000000 ]---
+[ 233.720486] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
+[ 233.721696] Mem abort info:
+[ 233.721935] ESR = 0x0000000096000004
+[ 233.722283] EC = 0x25: DABT (current EL), IL = 32 bits
+[ 233.722596] SET = 0, FnV = 0
+[ 233.722805] EA = 0, S1PTW = 0
+[ 233.723026] FSC = 0x04: level 0 translation fault
+[ 233.723458] Data abort info:
+[ 233.723734] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
+[ 233.724176] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
+[ 233.724589] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+[ 233.725075] user pgtable: 4k pages, 48-bit VAs, pgdp=0000000104943000
+[ 233.725592] [0000000000000000] pgd=0000000000000000, p4d=0000000000000000
+[ 233.726231] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
+[ 233.726720] Modules linked in:
+[ 233.727007] CPU: 0 PID: 9 Comm: kworker/0:1 Tainted: G W 6.5.0-rc1-00276-g20edcec23f92 #15
+[ 233.727777] Hardware name: linux,dummy-virt (DT)
+[ 233.728225] Workqueue: events update_pages_handler
+[ 233.728655] pstate: 200000c5 (nzCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+[ 233.729054] pc : rb_update_pages+0x1a8/0x3f8
+[ 233.729334] lr : rb_update_pages+0x154/0x3f8
+[ 233.729592] sp : ffff800082b9bd50
+[ 233.729792] x29: ffff800082b9bd50 x28: ffff8000825f7000 x27: 0000000000000000
+[ 233.730220] x26: 0000000000000000 x25: ffff800082a8b840 x24: ffff0000c0102418
+[ 233.730653] x23: 0000000000000000 x22: fffffc000304c880 x21: 0000000000000003
+[ 233.731105] x20: 00000000000001f4 x19: ffff0000c0102400 x18: ffff800082fcbc58
+[ 233.731727] x17: 0000000000000000 x16: 0000000000000001 x15: 0000000000000001
+[ 233.732282] x14: ffff8000825fe0c8 x13: 0000000000000001 x12: 0000000000000000
+[ 233.732709] x11: ffff8000826998a8 x10: 0000000000000ae0 x9 : ffff8000801b760c
+[ 233.733148] x8 : fefefefefefefeff x7 : 0000000000000018 x6 : ffff0000c03298c0
+[ 233.733553] x5 : 0000000000000002 x4 : 0000000000000000 x3 : 0000000000000000
+[ 233.733972] x2 : ffff0000c3a0b600 x1 : 0000000000000000 x0 : 0000000000000000
+[ 233.734418] Call trace:
+[ 233.734593] rb_update_pages+0x1a8/0x3f8
+[ 233.734853] update_pages_handler+0x1c/0x38
+[ 233.735148] process_one_work+0x1f0/0x468
+[ 233.735525] worker_thread+0x54/0x410
+[ 233.735852] kthread+0x124/0x138
+[ 233.736064] ret_from_fork+0x10/0x20
+[ 233.736387] Code: 92400000 910006b5 aa000021 aa0303f7 (f9400060)
+[ 233.736959] ---[ end trace 0000000000000000 ]---
+
+After analysis, the seq of the error is as follows [1-5]:
+
+int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,
+ int cpu_id)
+{
+ for_each_buffer_cpu(buffer, cpu) {
+ cpu_buffer = buffer->buffers[cpu];
+ //1. get cpu_buffer, aka cpu_buffer(A)
+ ...
+ ...
+ schedule_work_on(cpu,
+ &cpu_buffer->update_pages_work);
+ //2. 'update_pages_work' is queue on 'cpu', cpu_buffer(A) is passed to
+ // update_pages_handler, do the update process, set 'update_done' in
+ // complete(&cpu_buffer->update_done) and to wakeup resize process.
+ //---->
+ //3. Just at this moment, ring_buffer_swap_cpu is triggered,
+ //cpu_buffer(A) be swaped to cpu_buffer(B), the max_buffer.
+ //ring_buffer_swap_cpu is called as the 'Call trace' below.
+
+ Call trace:
+ dump_backtrace+0x0/0x2f8
+ show_stack+0x18/0x28
+ dump_stack+0x12c/0x188
+ ring_buffer_swap_cpu+0x2f8/0x328
+ update_max_tr_single+0x180/0x210
+ check_critical_timing+0x2b4/0x2c8
+ tracer_hardirqs_on+0x1c0/0x200
+ trace_hardirqs_on+0xec/0x378
+ el0_svc_common+0x64/0x260
+ do_el0_svc+0x90/0xf8
+ el0_svc+0x20/0x30
+ el0_sync_handler+0xb0/0xb8
+ el0_sync+0x180/0x1c0
+ //<----
+
+ /* wait for all the updates to complete */
+ for_each_buffer_cpu(buffer, cpu) {
+ cpu_buffer = buffer->buffers[cpu];
+ //4. get cpu_buffer, cpu_buffer(B) is used in the following process,
+ //the state of cpu_buffer(A) and cpu_buffer(B) is totally wrong.
+ //for example, cpu_buffer(A)->update_done will leave be set 1, and will
+ //not 'wait_for_completion' at the next resize round.
+ if (!cpu_buffer->nr_pages_to_update)
+ continue;
+
+ if (cpu_online(cpu))
+ wait_for_completion(&cpu_buffer->update_done);
+ cpu_buffer->nr_pages_to_update = 0;
+ }
+ ...
+}
+ //5. the state of cpu_buffer(A) and cpu_buffer(B) is totally wrong,
+ //Continuing to run in the wrong state, then oops occurs.
+
+Link: https://lore.kernel.org/linux-trace-kernel/202307191558478409990@zte.com.cn
+
+Signed-off-by: Chen Lin <chen.lin5@zte.com.cn>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/ring_buffer.c | 14 +++++++++++++-
+ kernel/trace/trace.c | 3 ++-
+ 2 files changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index c49ed619a64dd..de55107aef5d5 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -544,6 +544,7 @@ struct trace_buffer {
+ unsigned flags;
+ int cpus;
+ atomic_t record_disabled;
++ atomic_t resizing;
+ cpumask_var_t cpumask;
+
+ struct lock_class_key *reader_lock_key;
+@@ -2173,7 +2174,7 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,
+
+ /* prevent another thread from changing buffer sizes */
+ mutex_lock(&buffer->mutex);
+-
++ atomic_inc(&buffer->resizing);
+
+ if (cpu_id == RING_BUFFER_ALL_CPUS) {
+ /*
+@@ -2312,6 +2313,7 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,
+ atomic_dec(&buffer->record_disabled);
+ }
+
++ atomic_dec(&buffer->resizing);
+ mutex_unlock(&buffer->mutex);
+ return 0;
+
+@@ -2332,6 +2334,7 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,
+ }
+ }
+ out_err_unlock:
++ atomic_dec(&buffer->resizing);
+ mutex_unlock(&buffer->mutex);
+ return err;
+ }
+@@ -5539,6 +5542,15 @@ int ring_buffer_swap_cpu(struct trace_buffer *buffer_a,
+ if (local_read(&cpu_buffer_b->committing))
+ goto out_dec;
+
++ /*
++ * When resize is in progress, we cannot swap it because
++ * it will mess the state of the cpu buffer.
++ */
++ if (atomic_read(&buffer_a->resizing))
++ goto out_dec;
++ if (atomic_read(&buffer_b->resizing))
++ goto out_dec;
++
+ buffer_a->buffers[cpu] = cpu_buffer_b;
+ buffer_b->buffers[cpu] = cpu_buffer_a;
+
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index 709af9631be45..af33c5a4166d4 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -1885,9 +1885,10 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu)
+ * place on this CPU. We fail to record, but we reset
+ * the max trace buffer (no one writes directly to it)
+ * and flag that it failed.
++ * Another reason is resize is in progress.
+ */
+ trace_array_printk_buf(tr->max_buffer.buffer, _THIS_IP_,
+- "Failed to swap buffers due to commit in progress\n");
++ "Failed to swap buffers due to commit or resize in progress\n");
+ }
+
+ WARN_ON_ONCE(ret && ret != -EAGAIN && ret != -EBUSY);
+--
+2.40.1
+
--- /dev/null
+From 75304d33372a361dab7ea9d9f3af12e45a54c1f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Feb 2023 10:52:37 +0100
+Subject: selftests: forwarding: tc_actions: cleanup temporary files when test
+ is aborted
+
+From: Davide Caratti <dcaratti@redhat.com>
+
+[ Upstream commit f58531716ced8975a4ade108ef4af35f98722af7 ]
+
+remove temporary files created by 'mirred_egress_to_ingress_tcp' test
+in the cleanup() handler. Also, change variable names to avoid clashing
+with globals from lib.sh.
+
+Suggested-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Davide Caratti <dcaratti@redhat.com>
+Link: https://lore.kernel.org/r/091649045a017fc00095ecbb75884e5681f7025f.1676368027.git.dcaratti@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 5e8670610b93 ("selftests: forwarding: tc_actions: Use ncat instead of nc")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/net/forwarding/tc_actions.sh | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh
+index 919c0dd9fe4bc..a96cff8e72197 100755
+--- a/tools/testing/selftests/net/forwarding/tc_actions.sh
++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh
+@@ -201,10 +201,10 @@ mirred_egress_to_ingress_test()
+
+ mirred_egress_to_ingress_tcp_test()
+ {
+- local tmpfile=$(mktemp) tmpfile1=$(mktemp)
++ mirred_e2i_tf1=$(mktemp) mirred_e2i_tf2=$(mktemp)
+
+ RET=0
+- dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$tmpfile
++ dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred_e2i_tf1
+ tc filter add dev $h1 protocol ip pref 100 handle 100 egress flower \
+ $tcflags ip_proto tcp src_ip 192.0.2.1 dst_ip 192.0.2.2 \
+ action ct commit nat src addr 192.0.2.2 pipe \
+@@ -220,11 +220,11 @@ mirred_egress_to_ingress_tcp_test()
+ ip_proto icmp \
+ action drop
+
+- ip vrf exec v$h1 nc --recv-only -w10 -l -p 12345 -o $tmpfile1 &
++ ip vrf exec v$h1 nc --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 &
+ local rpid=$!
+- ip vrf exec v$h1 nc -w1 --send-only 192.0.2.2 12345 <$tmpfile
++ ip vrf exec v$h1 nc -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1
+ wait -n $rpid
+- cmp -s $tmpfile $tmpfile1
++ cmp -s $mirred_e2i_tf1 $mirred_e2i_tf2
+ check_err $? "server output check failed"
+
+ $MZ $h1 -c 10 -p 64 -a $h1mac -b $h1mac -A 192.0.2.1 -B 192.0.2.1 \
+@@ -241,7 +241,7 @@ mirred_egress_to_ingress_tcp_test()
+ tc filter del dev $h1 egress protocol ip pref 101 handle 101 flower
+ tc filter del dev $h1 ingress protocol ip pref 102 handle 102 flower
+
+- rm -f $tmpfile $tmpfile1
++ rm -f $mirred_e2i_tf1 $mirred_e2i_tf2
+ log_test "mirred_egress_to_ingress_tcp ($tcflags)"
+ }
+
+@@ -270,6 +270,8 @@ setup_prepare()
+
+ cleanup()
+ {
++ local tf
++
+ pre_cleanup
+
+ switch_destroy
+@@ -280,6 +282,8 @@ cleanup()
+
+ ip link set $swp2 address $swp2origmac
+ ip link set $swp1 address $swp1origmac
++
++ for tf in $mirred_e2i_tf1 $mirred_e2i_tf2; do rm -f $tf; done
+ }
+
+ mirred_egress_redirect_test()
+--
+2.40.1
+
--- /dev/null
+From 105bb70fdbf6b7ca8f2c4c5c18fcdc36c2f045f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Aug 2023 17:14:57 +0300
+Subject: selftests: forwarding: tc_actions: Use ncat instead of nc
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 5e8670610b93158ffacc3241f835454ff26a3469 ]
+
+The test relies on 'nc' being the netcat version from the nmap project.
+While this seems to be the case on Fedora, it is not the case on Ubuntu,
+resulting in failures such as [1].
+
+Fix by explicitly using the 'ncat' utility from the nmap project and the
+skip the test in case it is not installed.
+
+[1]
+ # timeout set to 0
+ # selftests: net/forwarding: tc_actions.sh
+ # TEST: gact drop and ok (skip_hw) [ OK ]
+ # TEST: mirred egress flower redirect (skip_hw) [ OK ]
+ # TEST: mirred egress flower mirror (skip_hw) [ OK ]
+ # TEST: mirred egress matchall mirror (skip_hw) [ OK ]
+ # TEST: mirred_egress_to_ingress (skip_hw) [ OK ]
+ # nc: invalid option -- '-'
+ # usage: nc [-46CDdFhklNnrStUuvZz] [-I length] [-i interval] [-M ttl]
+ # [-m minttl] [-O length] [-P proxy_username] [-p source_port]
+ # [-q seconds] [-s sourceaddr] [-T keyword] [-V rtable] [-W recvlimit]
+ # [-w timeout] [-X proxy_protocol] [-x proxy_address[:port]]
+ # [destination] [port]
+ # nc: invalid option -- '-'
+ # usage: nc [-46CDdFhklNnrStUuvZz] [-I length] [-i interval] [-M ttl]
+ # [-m minttl] [-O length] [-P proxy_username] [-p source_port]
+ # [-q seconds] [-s sourceaddr] [-T keyword] [-V rtable] [-W recvlimit]
+ # [-w timeout] [-X proxy_protocol] [-x proxy_address[:port]]
+ # [destination] [port]
+ # TEST: mirred_egress_to_ingress_tcp (skip_hw) [FAIL]
+ # server output check failed
+ # INFO: Could not test offloaded functionality
+ not ok 80 selftests: net/forwarding: tc_actions.sh # exit=1
+
+Fixes: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress")
+Reported-by: Mirsad Todorovac <mirsad.todorovac@alu.unizg.hr>
+Closes: https://lore.kernel.org/netdev/adc5e40d-d040-a65e-eb26-edf47dac5b02@alu.unizg.hr/
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Tested-by: Mirsad Todorovac <mirsad.todorovac@alu.unizg.hr>
+Reviewed-by: Hangbin Liu <liuhangbin@gmail.com>
+Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
+Link: https://lore.kernel.org/r/20230808141503.4060661-12-idosch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/tc_actions.sh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh
+index a96cff8e72197..b0f5e55d2d0b2 100755
+--- a/tools/testing/selftests/net/forwarding/tc_actions.sh
++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh
+@@ -9,6 +9,8 @@ NUM_NETIFS=4
+ source tc_common.sh
+ source lib.sh
+
++require_command ncat
++
+ tcflags="skip_hw"
+
+ h1_create()
+@@ -220,9 +222,9 @@ mirred_egress_to_ingress_tcp_test()
+ ip_proto icmp \
+ action drop
+
+- ip vrf exec v$h1 nc --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 &
++ ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 &
+ local rpid=$!
+- ip vrf exec v$h1 nc -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1
++ ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1
+ wait -n $rpid
+ cmp -s $mirred_e2i_tf1 $mirred_e2i_tf2
+ check_err $? "server output check failed"
+--
+2.40.1
+
--- /dev/null
+From 7c90ea613bf2d0f38dbb8b6f71aa64c229cedbfe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 May 2023 19:38:09 +0200
+Subject: serial: stm32: Ignore return value of uart_remove_one_port() in
+ .remove()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 6bd6cd29c92401a101993290051fa55078238a52 ]
+
+Returning early from stm32_usart_serial_remove() results in a resource
+leak as several cleanup functions are not called. The driver core ignores
+the return value and there is no possibility to clean up later.
+
+uart_remove_one_port() only returns non-zero if there is some
+inconsistency (i.e. stm32_usart_driver.state[port->line].uart_port == NULL).
+This should never happen, and even if it does it's a bad idea to exit
+early in the remove callback without cleaning up.
+
+This prepares changing the prototype of struct platform_driver::remove to
+return void. See commit 5c5a7680e67b ("platform: Provide a remove callback
+that returns no value") for further details about this quest.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20230512173810.131447-2-u.kleine-koenig@pengutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/stm32-usart.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
+index 28edbaf7bb329..2a9c4058824a8 100644
+--- a/drivers/tty/serial/stm32-usart.c
++++ b/drivers/tty/serial/stm32-usart.c
+@@ -1753,13 +1753,10 @@ static int stm32_usart_serial_remove(struct platform_device *pdev)
+ struct uart_port *port = platform_get_drvdata(pdev);
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+- int err;
+ u32 cr3;
+
+ pm_runtime_get_sync(&pdev->dev);
+- err = uart_remove_one_port(&stm32_usart_driver, port);
+- if (err)
+- return(err);
++ uart_remove_one_port(&stm32_usart_driver, port);
+
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+--
+2.40.1
+
--- /dev/null
+mmc-sdhci-f-sdh30-replace-with-sdhci_pltfm.patch
+cpuidle-psci-extend-information-in-log-about-osi-pc-.patch
+cpuidle-psci-move-enabling-osi-mode-after-power-doma.patch
+zsmalloc-consolidate-zs_pool-s-migrate_lock-and-size.patch
+zsmalloc-fix-races-between-modifications-of-fullness.patch
+selftests-forwarding-tc_actions-cleanup-temporary-fi.patch
+selftests-forwarding-tc_actions-use-ncat-instead-of-.patch
+net-smc-replace-mutex-rmbs_lock-and-sndbufs_lock-wit.patch
+net-smc-fix-setsockopt-and-sysctl-to-specify-same-bu.patch
+nvme-core-don-t-hold-rcu-read-lock-in-nvme_ns_chr_ur.patch
+net-phy-at803x-use-devm_regulator_get_enable_optiona.patch
+net-phy-at803x-fix-the-wol-setting-functions.patch
+drm-amdgpu-fix-calltrace-warning-in-amddrm_buddy_fin.patch
+drm-amdgpu-fix-integer-overflow-in-amdgpu_cs_pass1.patch
+drm-amdgpu-fix-memory-leak-in-mes-self-test.patch
+asoc-intel-sof_sdw-add-quirk-for-mtl-rvp.patch
+asoc-intel-sof_sdw-add-quirk-for-lnl-rvp.patch
+pci-tegra194-fix-possible-array-out-of-bounds-access.patch
+asoc-sof-amd-add-pci-revision-id-check.patch
+drm-stm-ltdc-fix-late-dereference-check.patch
+drm-rcar-du-remove-r-car-h3-es1.-workarounds.patch
+asoc-amd-vangogh-add-check-for-acp-config-flags-in-v.patch
+arm-dts-imx6dl-prtrvt-prtvt7-prti6q-prtwd2-fix-usb-r.patch
+asoc-intel-sof_sdw_rt_sdca_jack_common-test-sof_jack.patch
+asoc-intel-sof_sdw-add-support-for-rex-soundwire.patch
+iopoll-call-cpu_relax-in-busy-loops.patch
+asoc-sof-intel-fix-soundwire-hdaudio-mutual-exclusio.patch
+dma-remap-use-kvmalloc_array-kvfree-for-larger-dma-m.patch
+accel-habanalabs-add-pci-health-check-during-heartbe.patch
+hid-logitech-hidpp-add-usb-and-bluetooth-ids-for-the.patch
+iommu-amd-introduce-disable-irte-caching-support.patch
+drm-amdgpu-install-stub-fence-into-potential-unused-.patch
+drm-amd-display-apply-60us-prefetch-for-dcfclk-300mh.patch
+rdma-mlx5-return-the-firmware-result-upon-destroying.patch
+drm-amd-display-skip-dpp-dto-update-if-root-clock-is.patch
+drm-amd-display-enable-dcn314-dpp-rco.patch
+asoc-sof-core-free-the-firmware-trace-before-calling.patch
+hid-intel-ish-hid-ipc-add-arrow-lake-pci-device-id.patch
+alsa-hda-realtek-add-quirks-for-rog-ally-cs35l41-aud.patch
+smb-client-fix-warning-in-cifs_smb3_do_mount.patch
+cifs-fix-session-state-check-in-reconnect-to-avoid-u.patch
+serial-stm32-ignore-return-value-of-uart_remove_one_.patch
+led-qcom-lpg-fix-resource-leaks-in-for_each_availabl.patch
+media-v4l2-mem2mem-add-lock-to-protect-parameter-num.patch
+media-camss-set-vfe-bpl_alignment-to-16-for-sdm845-a.patch
+usb-gadget-u_serial-avoid-spinlock-recursion-in-__gs.patch
+usb-gadget-uvc-queue-empty-isoc-requests-if-no-video.patch
+media-platform-mediatek-vpu-fix-null-ptr-dereference.patch
+thunderbolt-read-retimer-nvm-authentication-status-p.patch
+usb-chipidea-imx-don-t-request-qos-for-imx8ulp.patch
+usb-chipidea-imx-add-missing-usb-phy-dpdm-wakeup-set.patch
+gfs2-fix-possible-data-races-in-gfs2_show_options.patch
+pcmcia-rsrc_nonstatic-fix-memory-leak-in-nonstatic_r.patch
+thunderbolt-add-intel-barlow-ridge-pci-id.patch
+thunderbolt-limit-intel-barlow-ridge-usb3-bandwidth.patch
+firewire-net-fix-use-after-free-in-fwnet_finish_inco.patch
+watchdog-sp5100_tco-support-hygon-fch-sch-server-con.patch
+bluetooth-l2cap-fix-use-after-free.patch
+bluetooth-btusb-add-mt7922-bluetooth-id-for-the-asus.patch
+ceph-try-to-dump-the-msgs-when-decoding-fails.patch
+drm-amdgpu-fix-potential-fence-use-after-free-v2.patch
+fs-ntfs3-enhance-sanity-check-while-generating-attr_.patch
+fs-ntfs3-fix-possible-null-pointer-dereferences-in-m.patch
+fs-ntfs3-mark-ntfs-dirty-when-on-disk-struct-is-corr.patch
+alsa-hda-realtek-add-quirks-for-unis-h3c-desktop-b76.patch
+alsa-hda-fix-a-possible-null-pointer-dereference-due.patch
+alsa-hda-realtek-add-quirk-for-asus-rog-gx650p.patch
+alsa-hda-realtek-add-quirk-for-asus-rog-ga402x.patch
+apparmor-fix-use-of-strcpy-in-policy_unpack_test.patch
+alsa-hda-realtek-add-quirk-for-asus-rog-gz301v.patch
+powerpc-kasan-disable-kcov-in-kasan-code.patch
+bluetooth-mgmt-use-correct-address-for-memcpy.patch
+ring-buffer-do-not-swap-cpu_buffer-during-resize-pro.patch
+igc-read-before-write-to-srrctl-register.patch
+drm-amd-display-save-restore-hdcp-state-when-display.patch
+drm-amd-display-phase3-mst-hdcp-for-multiple-display.patch
+drm-amd-display-fix-access-hdcp_workqueue-assert.patch
+kvm-arm64-vgic-v4-make-the-doorbell-request-robust-w.patch
+arm-dts-nxp-imx6sll-fix-wrong-property-name-in-usbph.patch
+fbdev-hyperv-fb-do-not-set-struct-fb_info.apertures.patch
+video-aperture-only-remove-sysfb-on-the-default-vga-.patch
+btrfs-move-out-now-unused-bg-from-the-reclaim-list.patch
+btrfs-convert-btrfs_block_group-needs_free_space-to-.patch
+btrfs-convert-btrfs_block_group-seq_zone-to-runtime-.patch
+btrfs-fix-use-after-free-of-new-block-group-that-bec.patch
+can-raw-fix-receiver-memory-leak.patch
+can-raw-fix-lockdep-issue-in-raw_release.patch
--- /dev/null
+From b5310ca59fb20b38dbdd8c3a50e818f87ac65864 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Jun 2023 16:24:37 -0300
+Subject: smb: client: fix warning in cifs_smb3_do_mount()
+
+From: Paulo Alcantara <pc@manguebit.com>
+
+[ Upstream commit 12c30f33cc6769bf411088a2872843c4f9ea32f9 ]
+
+This fixes the following warning reported by kernel test robot
+
+ fs/smb/client/cifsfs.c:982 cifs_smb3_do_mount() warn: possible
+ memory leak of 'cifs_sb'
+
+Link: https://lore.kernel.org/all/202306170124.CtQqzf0I-lkp@intel.com/
+Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/cifsfs.c | 28 ++++++++++------------------
+ 1 file changed, 10 insertions(+), 18 deletions(-)
+
+diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
+index 078df1e2dd18a..18d66497c42d1 100644
+--- a/fs/smb/client/cifsfs.c
++++ b/fs/smb/client/cifsfs.c
+@@ -883,11 +883,11 @@ struct dentry *
+ cifs_smb3_do_mount(struct file_system_type *fs_type,
+ int flags, struct smb3_fs_context *old_ctx)
+ {
+- int rc;
+- struct super_block *sb = NULL;
+- struct cifs_sb_info *cifs_sb = NULL;
+ struct cifs_mnt_data mnt_data;
++ struct cifs_sb_info *cifs_sb;
++ struct super_block *sb;
+ struct dentry *root;
++ int rc;
+
+ /*
+ * Prints in Kernel / CIFS log the attempted mount operation
+@@ -898,11 +898,9 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
+ else
+ cifs_info("Attempting to mount %s\n", old_ctx->UNC);
+
+- cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
+- if (cifs_sb == NULL) {
+- root = ERR_PTR(-ENOMEM);
+- goto out;
+- }
++ cifs_sb = kzalloc(sizeof(*cifs_sb), GFP_KERNEL);
++ if (!cifs_sb)
++ return ERR_PTR(-ENOMEM);
+
+ cifs_sb->ctx = kzalloc(sizeof(struct smb3_fs_context), GFP_KERNEL);
+ if (!cifs_sb->ctx) {
+@@ -945,10 +943,8 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
+
+ sb = sget(fs_type, cifs_match_super, cifs_set_super, flags, &mnt_data);
+ if (IS_ERR(sb)) {
+- root = ERR_CAST(sb);
+ cifs_umount(cifs_sb);
+- cifs_sb = NULL;
+- goto out;
++ return ERR_CAST(sb);
+ }
+
+ if (sb->s_root) {
+@@ -979,13 +975,9 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
+ deactivate_locked_super(sb);
+ return root;
+ out:
+- if (cifs_sb) {
+- if (!sb || IS_ERR(sb)) { /* otherwise kill_sb will handle */
+- kfree(cifs_sb->prepath);
+- smb3_cleanup_fs_context(cifs_sb->ctx);
+- kfree(cifs_sb);
+- }
+- }
++ kfree(cifs_sb->prepath);
++ smb3_cleanup_fs_context(cifs_sb->ctx);
++ kfree(cifs_sb);
+ return root;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 7e75d2f4eb98c46a1d1223648ec58c9a44624d18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Dec 2022 08:35:04 +0200
+Subject: thunderbolt: Add Intel Barlow Ridge PCI ID
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+[ Upstream commit 6f14a210661ce03988ef4ed3c8402037c8e06539 ]
+
+Intel Barlow Ridge is the first USB4 v2 controller from Intel. The
+controller exposes standard USB4 PCI class ID in typical configurations,
+however there is a way to configure it so that it uses a special class
+ID to allow using s different driver than the Windows inbox one. For
+this reason add the Barlow Ridge PCI ID to the Linux driver too so that
+the driver can attach regardless of the class ID.
+
+Tested-by: Pengfei Xu <pengfei.xu@intel.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thunderbolt/nhi.c | 2 ++
+ drivers/thunderbolt/nhi.h | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
+index 4a6a3802d7e51..288aaa05d0071 100644
+--- a/drivers/thunderbolt/nhi.c
++++ b/drivers/thunderbolt/nhi.c
+@@ -1479,6 +1479,8 @@ static struct pci_device_id nhi_ids[] = {
+ .driver_data = (kernel_ulong_t)&icl_nhi_ops },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MTL_P_NHI1),
+ .driver_data = (kernel_ulong_t)&icl_nhi_ops },
++ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_80G_NHI) },
++ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_40G_NHI) },
+
+ /* Any USB4 compliant host */
+ { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_USB4, ~0) },
+diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h
+index b0718020c6f59..c15a0c46c9cff 100644
+--- a/drivers/thunderbolt/nhi.h
++++ b/drivers/thunderbolt/nhi.h
+@@ -75,6 +75,8 @@ extern const struct tb_nhi_ops icl_nhi_ops;
+ #define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_BRIDGE 0x15ef
+ #define PCI_DEVICE_ID_INTEL_ADL_NHI0 0x463e
+ #define PCI_DEVICE_ID_INTEL_ADL_NHI1 0x466d
++#define PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_80G_NHI 0x5781
++#define PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_40G_NHI 0x5784
+ #define PCI_DEVICE_ID_INTEL_MTL_M_NHI0 0x7eb2
+ #define PCI_DEVICE_ID_INTEL_MTL_P_NHI0 0x7ec2
+ #define PCI_DEVICE_ID_INTEL_MTL_P_NHI1 0x7ec3
+--
+2.40.1
+
--- /dev/null
+From aa57746a837c47505c16cada5af4cd455abf7919 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 May 2023 10:45:53 +0300
+Subject: thunderbolt: Limit Intel Barlow Ridge USB3 bandwidth
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+[ Upstream commit f2bfa944080dcbb8eb56259dfd2c07204cbee17e ]
+
+Intel Barlow Ridge discrete USB4 host router has the same limitation as
+the previous generations so make sure the USB3 bandwidth limitation
+quirk is applied to Barlow Ridge too.
+
+Signed-off-by: Gil Fine <gil.fine@linux.intel.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thunderbolt/nhi.h | 2 ++
+ drivers/thunderbolt/quirks.c | 8 ++++++++
+ 2 files changed, 10 insertions(+)
+
+diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h
+index c15a0c46c9cff..0f029ce758825 100644
+--- a/drivers/thunderbolt/nhi.h
++++ b/drivers/thunderbolt/nhi.h
+@@ -77,6 +77,8 @@ extern const struct tb_nhi_ops icl_nhi_ops;
+ #define PCI_DEVICE_ID_INTEL_ADL_NHI1 0x466d
+ #define PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_80G_NHI 0x5781
+ #define PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_40G_NHI 0x5784
++#define PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HUB_80G_BRIDGE 0x5786
++#define PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HUB_40G_BRIDGE 0x57a4
+ #define PCI_DEVICE_ID_INTEL_MTL_M_NHI0 0x7eb2
+ #define PCI_DEVICE_ID_INTEL_MTL_P_NHI0 0x7ec2
+ #define PCI_DEVICE_ID_INTEL_MTL_P_NHI1 0x7ec3
+diff --git a/drivers/thunderbolt/quirks.c b/drivers/thunderbolt/quirks.c
+index 1157b8869bcca..8c2ee431fcde8 100644
+--- a/drivers/thunderbolt/quirks.c
++++ b/drivers/thunderbolt/quirks.c
+@@ -74,6 +74,14 @@ static const struct tb_quirk tb_quirks[] = {
+ quirk_usb3_maximum_bandwidth },
+ { 0x8087, PCI_DEVICE_ID_INTEL_MTL_P_NHI1, 0x0000, 0x0000,
+ quirk_usb3_maximum_bandwidth },
++ { 0x8087, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_80G_NHI, 0x0000, 0x0000,
++ quirk_usb3_maximum_bandwidth },
++ { 0x8087, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_40G_NHI, 0x0000, 0x0000,
++ quirk_usb3_maximum_bandwidth },
++ { 0x8087, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HUB_80G_BRIDGE, 0x0000, 0x0000,
++ quirk_usb3_maximum_bandwidth },
++ { 0x8087, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HUB_40G_BRIDGE, 0x0000, 0x0000,
++ quirk_usb3_maximum_bandwidth },
+ /*
+ * CLx is not supported on AMD USB4 Yellow Carp and Pink Sardine platforms.
+ */
+--
+2.40.1
+
--- /dev/null
+From 23f0f18b7a05f344a6deee893d9d438308e23a77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 May 2023 14:46:44 +0300
+Subject: thunderbolt: Read retimer NVM authentication status prior
+ tb_retimer_set_inbound_sbtx()
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+[ Upstream commit 1402ba08abae5cfa583ff1a40b99c098a0532d41 ]
+
+According to the USB4 retimer guide the correct order is immediately
+after sending ENUMERATE_RETIMERS so update the code to follow this.
+
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thunderbolt/retimer.c | 29 +++++++++++++++++++++--------
+ 1 file changed, 21 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/thunderbolt/retimer.c b/drivers/thunderbolt/retimer.c
+index 9cc28197dbc45..edbd92435b41a 100644
+--- a/drivers/thunderbolt/retimer.c
++++ b/drivers/thunderbolt/retimer.c
+@@ -187,6 +187,21 @@ static ssize_t nvm_authenticate_show(struct device *dev,
+ return ret;
+ }
+
++static void tb_retimer_nvm_authenticate_status(struct tb_port *port, u32 *status)
++{
++ int i;
++
++ tb_port_dbg(port, "reading NVM authentication status of retimers\n");
++
++ /*
++ * Before doing anything else, read the authentication status.
++ * If the retimer has it set, store it for the new retimer
++ * device instance.
++ */
++ for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++)
++ usb4_port_retimer_nvm_authenticate_status(port, i, &status[i]);
++}
++
+ static void tb_retimer_set_inbound_sbtx(struct tb_port *port)
+ {
+ int i;
+@@ -455,18 +470,16 @@ int tb_retimer_scan(struct tb_port *port, bool add)
+ return ret;
+
+ /*
+- * Enable sideband channel for each retimer. We can do this
+- * regardless whether there is device connected or not.
++ * Immediately after sending enumerate retimers read the
++ * authentication status of each retimer.
+ */
+- tb_retimer_set_inbound_sbtx(port);
++ tb_retimer_nvm_authenticate_status(port, status);
+
+ /*
+- * Before doing anything else, read the authentication status.
+- * If the retimer has it set, store it for the new retimer
+- * device instance.
++ * Enable sideband channel for each retimer. We can do this
++ * regardless whether there is device connected or not.
+ */
+- for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++)
+- usb4_port_retimer_nvm_authenticate_status(port, i, &status[i]);
++ tb_retimer_set_inbound_sbtx(port);
+
+ for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++) {
+ /*
+--
+2.40.1
+
--- /dev/null
+From 111d18a210bd6927375f04bb4ddb278c7591fc5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 May 2023 16:19:07 +0800
+Subject: usb: chipidea: imx: add missing USB PHY DPDM wakeup setting
+
+From: Xu Yang <xu.yang_2@nxp.com>
+
+[ Upstream commit 53d061c19dc4cb68409df6dc11c40389c8c42a75 ]
+
+USB PHY DPDM wakeup bit is enabled by default, when USB wakeup
+is not required(/sys/.../wakeup is disabled), this bit should be
+disabled, otherwise we will have unexpected wakeup if do USB device
+connect/disconnect while system sleep.
+This bit can be enabled for both host and device mode.
+
+Signed-off-by: Li Jun <jun.li@nxp.com>
+Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Message-ID: <20230517081907.3410465-3-xu.yang_2@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/chipidea/usbmisc_imx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c
+index bac0f5458cab9..2318c7906acdb 100644
+--- a/drivers/usb/chipidea/usbmisc_imx.c
++++ b/drivers/usb/chipidea/usbmisc_imx.c
+@@ -135,7 +135,7 @@
+ #define TXVREFTUNE0_MASK (0xf << 20)
+
+ #define MX6_USB_OTG_WAKEUP_BITS (MX6_BM_WAKEUP_ENABLE | MX6_BM_VBUS_WAKEUP | \
+- MX6_BM_ID_WAKEUP)
++ MX6_BM_ID_WAKEUP | MX6SX_BM_DPDM_WAKEUP_EN)
+
+ struct usbmisc_ops {
+ /* It's called once when probe a usb device */
+--
+2.40.1
+
--- /dev/null
+From bd95e18fcb530d2128250e1fe5a3f64875a8f5fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 18:40:07 +0800
+Subject: usb: chipidea: imx: don't request QoS for imx8ulp
+
+From: Xu Yang <xu.yang_2@nxp.com>
+
+[ Upstream commit 9a070e8e208995a9d638b538ed7abf28bd6ea6f0 ]
+
+Use dedicated imx8ulp usb compatible to remove QoS request
+since imx8ulp has no such limitation of imx7ulp: DMA will
+not work if system enters idle.
+
+Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
+Signed-off-by: Li Jun <jun.li@nxp.com>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Message-ID: <20230530104007.1294702-2-xu.yang_2@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/chipidea/ci_hdrc_imx.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
+index 9ffcecd3058c1..60b4de0a4f76d 100644
+--- a/drivers/usb/chipidea/ci_hdrc_imx.c
++++ b/drivers/usb/chipidea/ci_hdrc_imx.c
+@@ -70,6 +70,10 @@ static const struct ci_hdrc_imx_platform_flag imx7ulp_usb_data = {
+ CI_HDRC_PMQOS,
+ };
+
++static const struct ci_hdrc_imx_platform_flag imx8ulp_usb_data = {
++ .flags = CI_HDRC_SUPPORTS_RUNTIME_PM,
++};
++
+ static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
+ { .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},
+ { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
+@@ -80,6 +84,7 @@ static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
+ { .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data},
+ { .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data},
+ { .compatible = "fsl,imx7ulp-usb", .data = &imx7ulp_usb_data},
++ { .compatible = "fsl,imx8ulp-usb", .data = &imx8ulp_usb_data},
+ { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);
+--
+2.40.1
+
--- /dev/null
+From 3f5feb4ceeaf492e395b79533661dda9785c77f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 May 2023 18:57:52 +0530
+Subject: usb: gadget: u_serial: Avoid spinlock recursion in __gs_console_push
+
+From: Prashanth K <quic_prashk@quicinc.com>
+
+[ Upstream commit e5990469943c711cb00bfde6338d2add6c6d0bfe ]
+
+When serial console over USB is enabled, gs_console_connect
+queues gs_console_work, where it acquires the spinlock and
+queues the usb request, and this request goes to gadget layer.
+Now consider a situation where gadget layer prints something
+to dmesg, this will eventually call gs_console_write() which
+requires cons->lock. And this causes spinlock recursion. Avoid
+this by excluding usb_ep_queue from the spinlock.
+
+ spin_lock_irqsave //needs cons->lock
+ gs_console_write
+ .
+ .
+ _printk
+ __warn_printk
+ dev_warn/pr_err
+ .
+ .
+ [USB Gadget Layer]
+ .
+ .
+ usb_ep_queue
+ gs_console_work
+ __gs_console_push // acquires cons->lock
+ process_one_work
+
+Signed-off-by: Prashanth K <quic_prashk@quicinc.com>
+Link: https://lore.kernel.org/r/1683638872-6885-1-git-send-email-quic_prashk@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/u_serial.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c
+index ea2c5b6cde8cd..3c51355ccc94d 100644
+--- a/drivers/usb/gadget/function/u_serial.c
++++ b/drivers/usb/gadget/function/u_serial.c
+@@ -915,8 +915,11 @@ static void __gs_console_push(struct gs_console *cons)
+ }
+
+ req->length = size;
++
++ spin_unlock_irq(&cons->lock);
+ if (usb_ep_queue(ep, req, GFP_ATOMIC))
+ req->length = 0;
++ spin_lock_irq(&cons->lock);
+ }
+
+ static void gs_console_work(struct work_struct *work)
+--
+2.40.1
+
--- /dev/null
+From 48ed939b747c86c366b4d1c899b1cb09175fd6e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 May 2023 16:11:03 -0700
+Subject: usb: gadget: uvc: queue empty isoc requests if no video buffer is
+ available
+
+From: Avichal Rakesh <arakesh@google.com>
+
+[ Upstream commit c3ff12a92bd7072170978b8b41c2fa41b038139a ]
+
+ISOC transfers expect a certain cadence of requests being queued. Not
+keeping up with the expected rate of requests results in missed ISOC
+transfers (EXDEV). The application layer may or may not produce video
+frames to match this expectation, so uvc gadget driver must handle cases
+where the application is not queuing up buffers fast enough to fulfill
+ISOC requirements.
+
+Currently, uvc gadget driver waits for new video buffer to become available
+before queuing up usb requests. With this patch the gadget driver queues up
+0 length usb requests whenever there are no video buffers available. The
+USB controller's complete callback is used as the limiter for how quickly
+the 0 length packets will be queued. Video buffers are still queued as
+soon as they become available.
+
+Link: https://lore.kernel.org/CAMHf4WKbi6KBPQztj9FA4kPvESc1fVKrC8G73-cs6tTeQby9=w@mail.gmail.com/
+Signed-off-by: Avichal Rakesh <arakesh@google.com>
+Link: https://lore.kernel.org/r/20230508231103.1621375-1-arakesh@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/uvc_video.c | 32 ++++++++++++++++++-------
+ 1 file changed, 24 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
+index dd1c6b2ca7c6f..e81865978299c 100644
+--- a/drivers/usb/gadget/function/uvc_video.c
++++ b/drivers/usb/gadget/function/uvc_video.c
+@@ -386,6 +386,9 @@ static void uvcg_video_pump(struct work_struct *work)
+ struct uvc_buffer *buf;
+ unsigned long flags;
+ int ret;
++ bool buf_int;
++ /* video->max_payload_size is only set when using bulk transfer */
++ bool is_bulk = video->max_payload_size;
+
+ while (video->ep->enabled) {
+ /*
+@@ -408,20 +411,35 @@ static void uvcg_video_pump(struct work_struct *work)
+ */
+ spin_lock_irqsave(&queue->irqlock, flags);
+ buf = uvcg_queue_head(queue);
+- if (buf == NULL) {
++
++ if (buf != NULL) {
++ video->encode(req, video, buf);
++ /* Always interrupt for the last request of a video buffer */
++ buf_int = buf->state == UVC_BUF_STATE_DONE;
++ } else if (!(queue->flags & UVC_QUEUE_DISCONNECTED) && !is_bulk) {
++ /*
++ * No video buffer available; the queue is still connected and
++ * we're traferring over ISOC. Queue a 0 length request to
++ * prevent missed ISOC transfers.
++ */
++ req->length = 0;
++ buf_int = false;
++ } else {
++ /*
++ * Either queue has been disconnected or no video buffer
++ * available to bulk transfer. Either way, stop processing
++ * further.
++ */
+ spin_unlock_irqrestore(&queue->irqlock, flags);
+ break;
+ }
+
+- video->encode(req, video, buf);
+-
+ /*
+ * With usb3 we have more requests. This will decrease the
+ * interrupt load to a quarter but also catches the corner
+ * cases, which needs to be handled.
+ */
+- if (list_empty(&video->req_free) ||
+- buf->state == UVC_BUF_STATE_DONE ||
++ if (list_empty(&video->req_free) || buf_int ||
+ !(video->req_int_count %
+ DIV_ROUND_UP(video->uvc_num_requests, 4))) {
+ video->req_int_count = 0;
+@@ -441,8 +459,7 @@ static void uvcg_video_pump(struct work_struct *work)
+
+ /* Endpoint now owns the request */
+ req = NULL;
+- if (buf->state != UVC_BUF_STATE_DONE)
+- video->req_int_count++;
++ video->req_int_count++;
+ }
+
+ if (!req)
+@@ -527,4 +544,3 @@ int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc)
+ V4L2_BUF_TYPE_VIDEO_OUTPUT, &video->mutex);
+ return 0;
+ }
+-
+--
+2.40.1
+
--- /dev/null
+From c4284e875322cbfe92af99073db57754fd2ecb5b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Apr 2023 15:21:07 +0200
+Subject: video/aperture: Only remove sysfb on the default vga pci device
+
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+
+[ Upstream commit 5ae3716cfdcd286268133867f67d0803847acefc ]
+
+Instead of calling aperture_remove_conflicting_devices() to remove the
+conflicting devices, just call to aperture_detach_devices() to detach
+the device that matches the same PCI BAR / aperture range. Since the
+former is just a wrapper of the latter plus a sysfb_disable() call,
+and now that's done in this function but only for the primary devices.
+
+This fixes a regression introduced by commit ee7a69aa38d8 ("fbdev:
+Disable sysfb device registration when removing conflicting FBs"),
+where we remove the sysfb when loading a driver for an unrelated pci
+device, resulting in the user losing their efifb console or similar.
+
+Note that in practice this only is a problem with the nvidia blob,
+because that's the only gpu driver people might install which does not
+come with an fbdev driver of it's own. For everyone else the real gpu
+driver will restore a working console.
+
+Also note that in the referenced bug there's confusion that this same
+bug also happens on amdgpu. But that was just another amdgpu specific
+regression, which just happened to happen at roughly the same time and
+with the same user-observable symptoms. That bug is fixed now, see
+https://bugzilla.kernel.org/show_bug.cgi?id=216331#c15
+
+Note that we should not have any such issues on non-pci multi-gpu
+issues, because I could only find two such cases:
+- SoC with some external panel over spi or similar. These panel
+ drivers do not use drm_aperture_remove_conflicting_framebuffers(),
+ so no problem.
+- vga+mga, which is a direct console driver and entirely bypasses all
+ this.
+
+For the above reasons the cc: stable is just notionally, this patch
+will need a backport and that's up to nvidia if they care enough.
+
+v2:
+- Explain a bit better why other multi-gpu that aren't pci shouldn't
+ have any issues with making all this fully pci specific.
+
+v3
+- polish commit message (Javier)
+
+v4:
+- Fix commit message style (i.e., commit 1234 ("..."))
+- fix Daniel's S-o-b address
+
+v5:
+- add back an S-o-b tag with Daniel's Intel address
+
+Fixes: ee7a69aa38d8 ("fbdev: Disable sysfb device registration when removing conflicting FBs")
+Tested-by: Aaron Plattner <aplattner@nvidia.com>
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216303#c28
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Cc: Aaron Plattner <aplattner@nvidia.com>
+Cc: Javier Martinez Canillas <javierm@redhat.com>
+Cc: Thomas Zimmermann <tzimmermann@suse.de>
+Cc: Helge Deller <deller@gmx.de>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: <stable@vger.kernel.org> # v5.19+ (if someone else does the backport)
+Link: https://patchwork.freedesktop.org/patch/msgid/20230406132109.32050-8-tzimmermann@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/aperture.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c
+index 41e77de1ea82c..5c94abdb1ad6d 100644
+--- a/drivers/video/aperture.c
++++ b/drivers/video/aperture.c
+@@ -332,15 +332,16 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na
+ primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
+ #endif
+
++ if (primary)
++ sysfb_disable();
++
+ for (bar = 0; bar < PCI_STD_NUM_BARS; ++bar) {
+ if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM))
+ continue;
+
+ base = pci_resource_start(pdev, bar);
+ size = pci_resource_len(pdev, bar);
+- ret = aperture_remove_conflicting_devices(base, size, primary, name);
+- if (ret)
+- return ret;
++ aperture_detach_devices(base, size);
+ }
+
+ /*
+--
+2.40.1
+
--- /dev/null
+From 99bfb8dba31591343e8d64a45b067a781a0bcfcf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Jun 2023 11:19:07 +0800
+Subject: watchdog: sp5100_tco: support Hygon FCH/SCH (Server Controller Hub)
+
+From: Yuechao Zhao <yuechao.zhao@advantech.com.cn>
+
+[ Upstream commit 009637de1f65cff452ad49554d1e8ef9fda99e43 ]
+
+Add PCI_VENDOR_ID_HYGON(Hygon vendor id [0x1d94]) in this driver
+
+Signed-off-by: Yuechao Zhao <yuechao.zhao@advantech.com.cn>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lkml.kernel.org/r/20230612031907.796461-1-a345351830@gmail.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/sp5100_tco.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c
+index 14f8d8d90920f..2bd3dc25cb030 100644
+--- a/drivers/watchdog/sp5100_tco.c
++++ b/drivers/watchdog/sp5100_tco.c
+@@ -96,7 +96,7 @@ static enum tco_reg_layout tco_reg_layout(struct pci_dev *dev)
+ sp5100_tco_pci->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS &&
+ sp5100_tco_pci->revision >= AMD_ZEN_SMBUS_PCI_REV) {
+ return efch_mmio;
+- } else if (dev->vendor == PCI_VENDOR_ID_AMD &&
++ } else if ((dev->vendor == PCI_VENDOR_ID_AMD || dev->vendor == PCI_VENDOR_ID_HYGON) &&
+ ((dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS &&
+ dev->revision >= 0x41) ||
+ (dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS &&
+@@ -579,6 +579,8 @@ static const struct pci_device_id sp5100_tco_pci_tbl[] = {
+ PCI_ANY_ID, },
+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_KERNCZ_SMBUS, PCI_ANY_ID,
+ PCI_ANY_ID, },
++ { PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_KERNCZ_SMBUS, PCI_ANY_ID,
++ PCI_ANY_ID, },
+ { 0, }, /* End of list */
+ };
+ MODULE_DEVICE_TABLE(pci, sp5100_tco_pci_tbl);
+--
+2.40.1
+
--- /dev/null
+From 0832fb076c213535c0bcd3214e34ee091a183919 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 11:16:12 -0800
+Subject: zsmalloc: consolidate zs_pool's migrate_lock and size_class's locks
+
+From: Nhat Pham <nphamcs@gmail.com>
+
+[ Upstream commit c0547d0b6a4b637db05406b90ba82e1b2e71de56 ]
+
+Currently, zsmalloc has a hierarchy of locks, which includes a pool-level
+migrate_lock, and a lock for each size class. We have to obtain both
+locks in the hotpath in most cases anyway, except for zs_malloc. This
+exception will no longer exist when we introduce a LRU into the zs_pool
+for the new writeback functionality - we will need to obtain a pool-level
+lock to synchronize LRU handling even in zs_malloc.
+
+In preparation for zsmalloc writeback, consolidate these locks into a
+single pool-level lock, which drastically reduces the complexity of
+synchronization in zsmalloc.
+
+We have also benchmarked the lock consolidation to see the performance
+effect of this change on zram.
+
+First, we ran a synthetic FS workload on a server machine with 36 cores
+(same machine for all runs), using
+
+fs_mark -d ../zram1mnt -s 100000 -n 2500 -t 32 -k
+
+before and after for btrfs and ext4 on zram (FS usage is 80%).
+
+Here is the result (unit is file/second):
+
+With lock consolidation (btrfs):
+Average: 13520.2, Median: 13531.0, Stddev: 137.5961482019028
+
+Without lock consolidation (btrfs):
+Average: 13487.2, Median: 13575.0, Stddev: 309.08283679298665
+
+With lock consolidation (ext4):
+Average: 16824.4, Median: 16839.0, Stddev: 89.97388510006668
+
+Without lock consolidation (ext4)
+Average: 16958.0, Median: 16986.0, Stddev: 194.7370021336469
+
+As you can see, we observe a 0.3% regression for btrfs, and a 0.9%
+regression for ext4. This is a small, barely measurable difference in my
+opinion.
+
+For a more realistic scenario, we also tries building the kernel on zram.
+Here is the time it takes (in seconds):
+
+With lock consolidation (btrfs):
+real
+Average: 319.6, Median: 320.0, Stddev: 0.8944271909999159
+user
+Average: 6894.2, Median: 6895.0, Stddev: 25.528415540334656
+sys
+Average: 521.4, Median: 522.0, Stddev: 1.51657508881031
+
+Without lock consolidation (btrfs):
+real
+Average: 319.8, Median: 320.0, Stddev: 0.8366600265340756
+user
+Average: 6896.6, Median: 6899.0, Stddev: 16.04057355583023
+sys
+Average: 520.6, Median: 521.0, Stddev: 1.140175425099138
+
+With lock consolidation (ext4):
+real
+Average: 320.0, Median: 319.0, Stddev: 1.4142135623730951
+user
+Average: 6896.8, Median: 6878.0, Stddev: 28.621670111997307
+sys
+Average: 521.2, Median: 521.0, Stddev: 1.7888543819998317
+
+Without lock consolidation (ext4)
+real
+Average: 319.6, Median: 319.0, Stddev: 0.8944271909999159
+user
+Average: 6886.2, Median: 6887.0, Stddev: 16.93221781102523
+sys
+Average: 520.4, Median: 520.0, Stddev: 1.140175425099138
+
+The difference is entirely within the noise of a typical run on zram.
+This hardly justifies the complexity of maintaining both the pool lock and
+the class lock. In fact, for writeback, we would need to introduce yet
+another lock to prevent data races on the pool's LRU, further complicating
+the lock handling logic. IMHO, it is just better to collapse all of these
+into a single pool-level lock.
+
+Link: https://lkml.kernel.org/r/20221128191616.1261026-4-nphamcs@gmail.com
+Signed-off-by: Nhat Pham <nphamcs@gmail.com>
+Suggested-by: Johannes Weiner <hannes@cmpxchg.org>
+Acked-by: Minchan Kim <minchan@kernel.org>
+Acked-by: Johannes Weiner <hannes@cmpxchg.org>
+Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Cc: Dan Streetman <ddstreet@ieee.org>
+Cc: Nitin Gupta <ngupta@vflare.org>
+Cc: Seth Jennings <sjenning@redhat.com>
+Cc: Vitaly Wool <vitaly.wool@konsulko.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 4b5d1e47b694 ("zsmalloc: fix races between modifications of fullness and isolated")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/zsmalloc.c | 87 ++++++++++++++++++++++-----------------------------
+ 1 file changed, 37 insertions(+), 50 deletions(-)
+
+diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
+index d03941cace2c4..326faa751f0a4 100644
+--- a/mm/zsmalloc.c
++++ b/mm/zsmalloc.c
+@@ -33,8 +33,7 @@
+ /*
+ * lock ordering:
+ * page_lock
+- * pool->migrate_lock
+- * class->lock
++ * pool->lock
+ * zspage->lock
+ */
+
+@@ -192,7 +191,6 @@ static const int fullness_threshold_frac = 4;
+ static size_t huge_class_size;
+
+ struct size_class {
+- spinlock_t lock;
+ struct list_head fullness_list[NR_ZS_FULLNESS];
+ /*
+ * Size of objects stored in this class. Must be multiple
+@@ -247,8 +245,7 @@ struct zs_pool {
+ #ifdef CONFIG_COMPACTION
+ struct work_struct free_work;
+ #endif
+- /* protect page/zspage migration */
+- rwlock_t migrate_lock;
++ spinlock_t lock;
+ };
+
+ struct zspage {
+@@ -355,7 +352,7 @@ static void cache_free_zspage(struct zs_pool *pool, struct zspage *zspage)
+ kmem_cache_free(pool->zspage_cachep, zspage);
+ }
+
+-/* class->lock(which owns the handle) synchronizes races */
++/* pool->lock(which owns the handle) synchronizes races */
+ static void record_obj(unsigned long handle, unsigned long obj)
+ {
+ *(unsigned long *)handle = obj;
+@@ -452,7 +449,7 @@ static __maybe_unused int is_first_page(struct page *page)
+ return PagePrivate(page);
+ }
+
+-/* Protected by class->lock */
++/* Protected by pool->lock */
+ static inline int get_zspage_inuse(struct zspage *zspage)
+ {
+ return zspage->inuse;
+@@ -597,13 +594,13 @@ static int zs_stats_size_show(struct seq_file *s, void *v)
+ if (class->index != i)
+ continue;
+
+- spin_lock(&class->lock);
++ spin_lock(&pool->lock);
+ class_almost_full = zs_stat_get(class, CLASS_ALMOST_FULL);
+ class_almost_empty = zs_stat_get(class, CLASS_ALMOST_EMPTY);
+ obj_allocated = zs_stat_get(class, OBJ_ALLOCATED);
+ obj_used = zs_stat_get(class, OBJ_USED);
+ freeable = zs_can_compact(class);
+- spin_unlock(&class->lock);
++ spin_unlock(&pool->lock);
+
+ objs_per_zspage = class->objs_per_zspage;
+ pages_used = obj_allocated / objs_per_zspage *
+@@ -916,7 +913,7 @@ static void __free_zspage(struct zs_pool *pool, struct size_class *class,
+
+ get_zspage_mapping(zspage, &class_idx, &fg);
+
+- assert_spin_locked(&class->lock);
++ assert_spin_locked(&pool->lock);
+
+ VM_BUG_ON(get_zspage_inuse(zspage));
+ VM_BUG_ON(fg != ZS_EMPTY);
+@@ -1247,19 +1244,19 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle,
+ BUG_ON(in_interrupt());
+
+ /* It guarantees it can get zspage from handle safely */
+- read_lock(&pool->migrate_lock);
++ spin_lock(&pool->lock);
+ obj = handle_to_obj(handle);
+ obj_to_location(obj, &page, &obj_idx);
+ zspage = get_zspage(page);
+
+ /*
+- * migration cannot move any zpages in this zspage. Here, class->lock
++ * migration cannot move any zpages in this zspage. Here, pool->lock
+ * is too heavy since callers would take some time until they calls
+ * zs_unmap_object API so delegate the locking from class to zspage
+ * which is smaller granularity.
+ */
+ migrate_read_lock(zspage);
+- read_unlock(&pool->migrate_lock);
++ spin_unlock(&pool->lock);
+
+ class = zspage_class(pool, zspage);
+ off = (class->size * obj_idx) & ~PAGE_MASK;
+@@ -1412,8 +1409,8 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size, gfp_t gfp)
+ size += ZS_HANDLE_SIZE;
+ class = pool->size_class[get_size_class_index(size)];
+
+- /* class->lock effectively protects the zpage migration */
+- spin_lock(&class->lock);
++ /* pool->lock effectively protects the zpage migration */
++ spin_lock(&pool->lock);
+ zspage = find_get_zspage(class);
+ if (likely(zspage)) {
+ obj = obj_malloc(pool, zspage, handle);
+@@ -1421,12 +1418,12 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size, gfp_t gfp)
+ fix_fullness_group(class, zspage);
+ record_obj(handle, obj);
+ class_stat_inc(class, OBJ_USED, 1);
+- spin_unlock(&class->lock);
++ spin_unlock(&pool->lock);
+
+ return handle;
+ }
+
+- spin_unlock(&class->lock);
++ spin_unlock(&pool->lock);
+
+ zspage = alloc_zspage(pool, class, gfp);
+ if (!zspage) {
+@@ -1434,7 +1431,7 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size, gfp_t gfp)
+ return (unsigned long)ERR_PTR(-ENOMEM);
+ }
+
+- spin_lock(&class->lock);
++ spin_lock(&pool->lock);
+ obj = obj_malloc(pool, zspage, handle);
+ newfg = get_fullness_group(class, zspage);
+ insert_zspage(class, zspage, newfg);
+@@ -1447,7 +1444,7 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size, gfp_t gfp)
+
+ /* We completely set up zspage so mark them as movable */
+ SetZsPageMovable(pool, zspage);
+- spin_unlock(&class->lock);
++ spin_unlock(&pool->lock);
+
+ return handle;
+ }
+@@ -1491,16 +1488,14 @@ void zs_free(struct zs_pool *pool, unsigned long handle)
+ return;
+
+ /*
+- * The pool->migrate_lock protects the race with zpage's migration
++ * The pool->lock protects the race with zpage's migration
+ * so it's safe to get the page from handle.
+ */
+- read_lock(&pool->migrate_lock);
++ spin_lock(&pool->lock);
+ obj = handle_to_obj(handle);
+ obj_to_page(obj, &f_page);
+ zspage = get_zspage(f_page);
+ class = zspage_class(pool, zspage);
+- spin_lock(&class->lock);
+- read_unlock(&pool->migrate_lock);
+
+ obj_free(class->size, obj);
+ class_stat_dec(class, OBJ_USED, 1);
+@@ -1510,7 +1505,7 @@ void zs_free(struct zs_pool *pool, unsigned long handle)
+
+ free_zspage(pool, class, zspage);
+ out:
+- spin_unlock(&class->lock);
++ spin_unlock(&pool->lock);
+ cache_free_handle(pool, handle);
+ }
+ EXPORT_SYMBOL_GPL(zs_free);
+@@ -1867,16 +1862,12 @@ static int zs_page_migrate(struct page *newpage, struct page *page,
+ pool = zspage->pool;
+
+ /*
+- * The pool migrate_lock protects the race between zpage migration
++ * The pool's lock protects the race between zpage migration
+ * and zs_free.
+ */
+- write_lock(&pool->migrate_lock);
++ spin_lock(&pool->lock);
+ class = zspage_class(pool, zspage);
+
+- /*
+- * the class lock protects zpage alloc/free in the zspage.
+- */
+- spin_lock(&class->lock);
+ /* the migrate_write_lock protects zpage access via zs_map_object */
+ migrate_write_lock(zspage);
+
+@@ -1906,10 +1897,9 @@ static int zs_page_migrate(struct page *newpage, struct page *page,
+ replace_sub_page(class, zspage, newpage, page);
+ /*
+ * Since we complete the data copy and set up new zspage structure,
+- * it's okay to release migration_lock.
++ * it's okay to release the pool's lock.
+ */
+- write_unlock(&pool->migrate_lock);
+- spin_unlock(&class->lock);
++ spin_unlock(&pool->lock);
+ dec_zspage_isolation(zspage);
+ migrate_write_unlock(zspage);
+
+@@ -1964,9 +1954,9 @@ static void async_free_zspage(struct work_struct *work)
+ if (class->index != i)
+ continue;
+
+- spin_lock(&class->lock);
++ spin_lock(&pool->lock);
+ list_splice_init(&class->fullness_list[ZS_EMPTY], &free_pages);
+- spin_unlock(&class->lock);
++ spin_unlock(&pool->lock);
+ }
+
+ list_for_each_entry_safe(zspage, tmp, &free_pages, list) {
+@@ -1976,9 +1966,9 @@ static void async_free_zspage(struct work_struct *work)
+ get_zspage_mapping(zspage, &class_idx, &fullness);
+ VM_BUG_ON(fullness != ZS_EMPTY);
+ class = pool->size_class[class_idx];
+- spin_lock(&class->lock);
++ spin_lock(&pool->lock);
+ __free_zspage(pool, class, zspage);
+- spin_unlock(&class->lock);
++ spin_unlock(&pool->lock);
+ }
+ };
+
+@@ -2039,10 +2029,11 @@ static unsigned long __zs_compact(struct zs_pool *pool,
+ struct zspage *dst_zspage = NULL;
+ unsigned long pages_freed = 0;
+
+- /* protect the race between zpage migration and zs_free */
+- write_lock(&pool->migrate_lock);
+- /* protect zpage allocation/free */
+- spin_lock(&class->lock);
++ /*
++ * protect the race between zpage migration and zs_free
++ * as well as zpage allocation/free
++ */
++ spin_lock(&pool->lock);
+ while ((src_zspage = isolate_zspage(class, true))) {
+ /* protect someone accessing the zspage(i.e., zs_map_object) */
+ migrate_write_lock(src_zspage);
+@@ -2067,7 +2058,7 @@ static unsigned long __zs_compact(struct zs_pool *pool,
+ putback_zspage(class, dst_zspage);
+ migrate_write_unlock(dst_zspage);
+ dst_zspage = NULL;
+- if (rwlock_is_contended(&pool->migrate_lock))
++ if (spin_is_contended(&pool->lock))
+ break;
+ }
+
+@@ -2084,11 +2075,9 @@ static unsigned long __zs_compact(struct zs_pool *pool,
+ pages_freed += class->pages_per_zspage;
+ } else
+ migrate_write_unlock(src_zspage);
+- spin_unlock(&class->lock);
+- write_unlock(&pool->migrate_lock);
++ spin_unlock(&pool->lock);
+ cond_resched();
+- write_lock(&pool->migrate_lock);
+- spin_lock(&class->lock);
++ spin_lock(&pool->lock);
+ }
+
+ if (src_zspage) {
+@@ -2096,8 +2085,7 @@ static unsigned long __zs_compact(struct zs_pool *pool,
+ migrate_write_unlock(src_zspage);
+ }
+
+- spin_unlock(&class->lock);
+- write_unlock(&pool->migrate_lock);
++ spin_unlock(&pool->lock);
+
+ return pages_freed;
+ }
+@@ -2200,7 +2188,7 @@ struct zs_pool *zs_create_pool(const char *name)
+ return NULL;
+
+ init_deferred_free(pool);
+- rwlock_init(&pool->migrate_lock);
++ spin_lock_init(&pool->lock);
+
+ pool->name = kstrdup(name, GFP_KERNEL);
+ if (!pool->name)
+@@ -2271,7 +2259,6 @@ struct zs_pool *zs_create_pool(const char *name)
+ class->index = i;
+ class->pages_per_zspage = pages_per_zspage;
+ class->objs_per_zspage = objs_per_zspage;
+- spin_lock_init(&class->lock);
+ pool->size_class[i] = class;
+ for (fullness = ZS_EMPTY; fullness < NR_ZS_FULLNESS;
+ fullness++)
+--
+2.40.1
+
--- /dev/null
+From 949c063d056a95ddf69de6c8666f48c55f584fc6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jul 2023 14:37:01 +0800
+Subject: zsmalloc: fix races between modifications of fullness and isolated
+
+From: Andrew Yang <andrew.yang@mediatek.com>
+
+[ Upstream commit 4b5d1e47b69426c0f7491d97d73ad0152d02d437 ]
+
+We encountered many kernel exceptions of VM_BUG_ON(zspage->isolated ==
+0) in dec_zspage_isolation() and BUG_ON(!pages[1]) in zs_unmap_object()
+lately. This issue only occurs when migration and reclamation occur at
+the same time.
+
+With our memory stress test, we can reproduce this issue several times
+a day. We have no idea why no one else encountered this issue. BTW,
+we switched to the new kernel version with this defect a few months
+ago.
+
+Since fullness and isolated share the same unsigned int, modifications of
+them should be protected by the same lock.
+
+[andrew.yang@mediatek.com: move comment]
+ Link: https://lkml.kernel.org/r/20230727062910.6337-1-andrew.yang@mediatek.com
+Link: https://lkml.kernel.org/r/20230721063705.11455-1-andrew.yang@mediatek.com
+Fixes: c4549b871102 ("zsmalloc: remove zspage isolation for migration")
+Signed-off-by: Andrew Yang <andrew.yang@mediatek.com>
+Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Cc: Matthias Brugger <matthias.bgg@gmail.com>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/zsmalloc.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
+index 326faa751f0a4..2f5e6d35b03bd 100644
+--- a/mm/zsmalloc.c
++++ b/mm/zsmalloc.c
+@@ -1816,6 +1816,7 @@ static void replace_sub_page(struct size_class *class, struct zspage *zspage,
+
+ static bool zs_page_isolate(struct page *page, isolate_mode_t mode)
+ {
++ struct zs_pool *pool;
+ struct zspage *zspage;
+
+ /*
+@@ -1826,9 +1827,10 @@ static bool zs_page_isolate(struct page *page, isolate_mode_t mode)
+ VM_BUG_ON_PAGE(PageIsolated(page), page);
+
+ zspage = get_zspage(page);
+- migrate_write_lock(zspage);
++ pool = zspage->pool;
++ spin_lock(&pool->lock);
+ inc_zspage_isolation(zspage);
+- migrate_write_unlock(zspage);
++ spin_unlock(&pool->lock);
+
+ return true;
+ }
+@@ -1895,12 +1897,12 @@ static int zs_page_migrate(struct page *newpage, struct page *page,
+ kunmap_atomic(s_addr);
+
+ replace_sub_page(class, zspage, newpage, page);
++ dec_zspage_isolation(zspage);
+ /*
+ * Since we complete the data copy and set up new zspage structure,
+ * it's okay to release the pool's lock.
+ */
+ spin_unlock(&pool->lock);
+- dec_zspage_isolation(zspage);
+ migrate_write_unlock(zspage);
+
+ get_page(newpage);
+@@ -1917,15 +1919,17 @@ static int zs_page_migrate(struct page *newpage, struct page *page,
+
+ static void zs_page_putback(struct page *page)
+ {
++ struct zs_pool *pool;
+ struct zspage *zspage;
+
+ VM_BUG_ON_PAGE(!PageMovable(page), page);
+ VM_BUG_ON_PAGE(!PageIsolated(page), page);
+
+ zspage = get_zspage(page);
+- migrate_write_lock(zspage);
++ pool = zspage->pool;
++ spin_lock(&pool->lock);
+ dec_zspage_isolation(zspage);
+- migrate_write_unlock(zspage);
++ spin_unlock(&pool->lock);
+ }
+
+ static const struct movable_operations zsmalloc_mops = {
+--
+2.40.1
+