--- /dev/null
+From 8945b66f1ed6f2936b2531c7b289bee39d36dc89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Feb 2024 11:46:28 +0800
+Subject: ACPI: CPPC: enable AMD CPPC V2 support for family 17h processors
+
+From: Perry Yuan <perry.yuan@amd.com>
+
+[ Upstream commit a51ab63b297ce9e26e3ffb9be896018a42d5f32f ]
+
+As there are some AMD processors which only support CPPC V2 firmware and
+BIOS implementation, the amd_pstate driver will be failed to load when
+system booting with below kernel warning message:
+
+[ 0.477523] amd_pstate: the _CPC object is not present in SBIOS or ACPI disabled
+
+To make the amd_pstate driver can be loaded on those TR40 processors, it
+needs to match x86_model from 0x30 to 0x7F for family 17H.
+With the change, the system can load amd_pstate driver as expected.
+
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Reported-by: Gino Badouri <badouri.g@gmail.com>
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218171
+Fixes: fbd74d1689 ("ACPI: CPPC: Fix enabling CPPC on AMD systems with shared memory")
+Signed-off-by: Perry Yuan <perry.yuan@amd.com>
+Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/acpi/cppc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c
+index 8d8752b44f113..ff8f25faca3dd 100644
+--- a/arch/x86/kernel/acpi/cppc.c
++++ b/arch/x86/kernel/acpi/cppc.c
+@@ -20,7 +20,7 @@ bool cpc_supported_by_cpu(void)
+ (boot_cpu_data.x86_model >= 0x20 && boot_cpu_data.x86_model <= 0x2f)))
+ return true;
+ else if (boot_cpu_data.x86 == 0x17 &&
+- boot_cpu_data.x86_model >= 0x70 && boot_cpu_data.x86_model <= 0x7f)
++ boot_cpu_data.x86_model >= 0x30 && boot_cpu_data.x86_model <= 0x7f)
+ return true;
+ return boot_cpu_has(X86_FEATURE_CPPC);
+ }
+--
+2.43.0
+
--- /dev/null
+From 1388ccc2b21d270a0f1283f9634c7a51425e42b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Feb 2024 01:41:58 +0100
+Subject: ACPI: processor_idle: Fix memory leak in acpi_processor_power_exit()
+
+From: Armin Wolf <W_Armin@gmx.de>
+
+[ Upstream commit e18afcb7b2a12b635ac10081f943fcf84ddacc51 ]
+
+After unregistering the CPU idle device, the memory associated with
+it is not freed, leading to a memory leak:
+
+unreferenced object 0xffff896282f6c000 (size 1024):
+ comm "swapper/0", pid 1, jiffies 4294893170
+ hex dump (first 32 bytes):
+ 00 00 00 00 0b 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ backtrace (crc 8836a742):
+ [<ffffffff993495ed>] kmalloc_trace+0x29d/0x340
+ [<ffffffff9972f3b3>] acpi_processor_power_init+0xf3/0x1c0
+ [<ffffffff9972d263>] __acpi_processor_start+0xd3/0xf0
+ [<ffffffff9972d2bc>] acpi_processor_start+0x2c/0x50
+ [<ffffffff99805872>] really_probe+0xe2/0x480
+ [<ffffffff99805c98>] __driver_probe_device+0x78/0x160
+ [<ffffffff99805daf>] driver_probe_device+0x1f/0x90
+ [<ffffffff9980601e>] __driver_attach+0xce/0x1c0
+ [<ffffffff99803170>] bus_for_each_dev+0x70/0xc0
+ [<ffffffff99804822>] bus_add_driver+0x112/0x210
+ [<ffffffff99807245>] driver_register+0x55/0x100
+ [<ffffffff9aee4acb>] acpi_processor_driver_init+0x3b/0xc0
+ [<ffffffff990012d1>] do_one_initcall+0x41/0x300
+ [<ffffffff9ae7c4b0>] kernel_init_freeable+0x320/0x470
+ [<ffffffff99b231f6>] kernel_init+0x16/0x1b0
+ [<ffffffff99042e6d>] ret_from_fork+0x2d/0x50
+
+Fix this by freeing the CPU idle device after unregistering it.
+
+Fixes: 3d339dcbb56d ("cpuidle / ACPI : move cpuidle_device field out of the acpi_processor_power structure")
+Signed-off-by: Armin Wolf <W_Armin@gmx.de>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/processor_idle.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
+index fc5b5b2c9e819..6f613eef28879 100644
+--- a/drivers/acpi/processor_idle.c
++++ b/drivers/acpi/processor_idle.c
+@@ -1431,6 +1431,8 @@ int acpi_processor_power_exit(struct acpi_processor *pr)
+ acpi_processor_registered--;
+ if (acpi_processor_registered == 0)
+ cpuidle_unregister_driver(&acpi_idle_driver);
++
++ kfree(dev);
+ }
+
+ pr->flags.power_setup_done = 0;
+--
+2.43.0
+
--- /dev/null
+From 96bc4a8b670f0d43be42e7cff482cb8f85e91b48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jan 2024 12:55:18 -0400
+Subject: ACPI: resource: Add Infinity laptops to irq1_edge_low_force_override
+
+From: David McFarland <corngood@gmail.com>
+
+[ Upstream commit e2605d4039a42a03000856b3229932455717b48b ]
+
+A user reported a keyboard problem similar to ones reported with other
+Zen laptops, on an Infinity E15-5A165-BM.
+
+Add board name matches for this model and one (untested) close relative
+to irq1_edge_low_force_override.
+
+Link: https://lemmy.ml/post/9864736
+Link: https://www.infinitygaming.com.au/bios/
+Link: https://lore.kernel.org/linux-acpi/20231006123304.32686-1-hdegoede@redhat.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: 021a67d09615 ("ACPI: resource: Add MAIBENBEN X577 to irq1_edge_low_force_override")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/resource.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
+index 5ebeb0d7b6be0..35a98a5916f63 100644
+--- a/drivers/acpi/resource.c
++++ b/drivers/acpi/resource.c
+@@ -543,6 +543,18 @@ static const struct dmi_system_id lg_laptop[] = {
+ DMI_MATCH(DMI_BOARD_NAME, "17U70P"),
+ },
+ },
++ {
++ /* Infinity E15-5A165-BM */
++ .matches = {
++ DMI_MATCH(DMI_BOARD_NAME, "GM5RG1E0009COM"),
++ },
++ },
++ {
++ /* Infinity E15-5A305-1M */
++ .matches = {
++ DMI_MATCH(DMI_BOARD_NAME, "GM5RGEE0016COM"),
++ },
++ },
+ { }
+ };
+
+--
+2.43.0
+
--- /dev/null
+From faea874bcd50181ab2c57141a2f54a33a28622c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Feb 2024 19:24:08 +0300
+Subject: ACPI: resource: Add MAIBENBEN X577 to irq1_edge_low_force_override
+
+From: Maxim Kudinov <m.kudinovv@gmail.com>
+
+[ Upstream commit 021a67d096154893cd1d883c7be0097e2ee327fd ]
+
+A known issue on some Zen laptops, keyboard stopped working due to commit
+9946e39fe8d0 fael@kernel.org("ACPI: resource: skip IRQ override on AMD
+Zen platforms") on kernel 5.19.10.
+
+The ACPI IRQ override is required for this board due to buggy DSDT, thus
+adding the board vendor and name to irq1_edge_low_force_override fixes
+the issue.
+
+Fixes: 9946e39fe8d0 ("ACPI: resource: skip IRQ override on AMD Zen platforms")
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=217394
+Link: https://lore.kernel.org/linux-acpi/20231006123304.32686-1-hdegoede@redhat.com/
+Tested-by: Maxim Trofimov <maxvereschagin@gmail.com>
+Signed-off-by: Maxim Kudinov <m.kudinovv@gmail.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/resource.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
+index 8420d97287f86..1c5c1a269fbee 100644
+--- a/drivers/acpi/resource.c
++++ b/drivers/acpi/resource.c
+@@ -569,6 +569,13 @@ static const struct dmi_system_id lg_laptop[] = {
+ DMI_MATCH(DMI_BOARD_NAME, "LL6FA"),
+ },
+ },
++ {
++ /* MAIBENBEN X577 */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "MAIBENBEN"),
++ DMI_MATCH(DMI_BOARD_NAME, "X577"),
++ },
++ },
+ { }
+ };
+
+--
+2.43.0
+
--- /dev/null
+From 63ff7c65e0e5ee363addf21ff3eb797d26b81a1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Feb 2024 12:30:09 +0000
+Subject: ACPI: resource: Do IRQ override on Lunnen Ground laptops
+
+From: Alexey I. Froloff <raorn@raorn.name>
+
+[ Upstream commit e23ad54fef186aa66007895be1382c88f1ee2bf7 ]
+
+The Lunnen Ground 15 and 16 needs IRQ overriding for the keyboard to
+work.
+
+Adding an entries for these laptops to the override_table makes the
+internal keyboard functional.
+
+Signed-off-by: Alexey I. Froloff <raorn@raorn.name>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: 021a67d09615 ("ACPI: resource: Add MAIBENBEN X577 to irq1_edge_low_force_override")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/resource.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
+index 35a98a5916f63..8420d97287f86 100644
+--- a/drivers/acpi/resource.c
++++ b/drivers/acpi/resource.c
+@@ -555,6 +555,20 @@ static const struct dmi_system_id lg_laptop[] = {
+ DMI_MATCH(DMI_BOARD_NAME, "GM5RGEE0016COM"),
+ },
+ },
++ {
++ /* Lunnen Ground 15 / AMD Ryzen 5 5500U */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Lunnen"),
++ DMI_MATCH(DMI_BOARD_NAME, "LLL5DAW"),
++ },
++ },
++ {
++ /* Lunnen Ground 16 / AMD Ryzen 7 5800U */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "Lunnen"),
++ DMI_MATCH(DMI_BOARD_NAME, "LL6FA"),
++ },
++ },
+ { }
+ };
+
+--
+2.43.0
+
--- /dev/null
+From 12996394ad1d8182f454c2313afe938bf4f11ca6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Feb 2024 17:35:27 +0100
+Subject: ACPI: scan: Fix device check notification handling
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 793551c965116d9dfaf0550dacae1396a20efa69 ]
+
+It is generally invalid to fail a Device Check notification if the scan
+handler has not been attached to the given device after a bus rescan,
+because there may be valid reasons for the scan handler to refuse
+attaching to the device (for example, the device is not ready).
+
+For this reason, modify acpi_scan_device_check() to return 0 in that
+case without printing a warning.
+
+While at it, reduce the log level of the "already enumerated" message
+in the same function, because it is only interesting when debugging
+notification handling
+
+Fixes: 443fc8202272 ("ACPI / hotplug: Rework generic code to handle suprise removals")
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/scan.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
+index 94154a849a3ea..293cdf486fd81 100644
+--- a/drivers/acpi/scan.c
++++ b/drivers/acpi/scan.c
+@@ -315,18 +315,14 @@ static int acpi_scan_device_check(struct acpi_device *adev)
+ * again).
+ */
+ if (adev->handler) {
+- dev_warn(&adev->dev, "Already enumerated\n");
+- return -EALREADY;
++ dev_dbg(&adev->dev, "Already enumerated\n");
++ return 0;
+ }
+ error = acpi_bus_scan(adev->handle);
+ if (error) {
+ dev_warn(&adev->dev, "Namespace scan failure\n");
+ return error;
+ }
+- if (!adev->handler) {
+- dev_warn(&adev->dev, "Enumeration failure\n");
+- error = -ENODEV;
+- }
+ } else {
+ error = acpi_scan_device_not_present(adev);
+ }
+--
+2.43.0
+
--- /dev/null
+From ece64564daecb5e4f0714059c4dad8513d298a41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jan 2024 09:08:52 -0800
+Subject: af_unix: Annotate data-race of gc_in_progress in wait_for_unix_gc().
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 31e03207119a535d0b0e3b3a7f91983aeb2cb14d ]
+
+gc_in_progress is changed under spin_lock(&unix_gc_lock),
+but wait_for_unix_gc() reads it locklessly.
+
+Let's use READ_ONCE().
+
+Fixes: 5f23b734963e ("net: Fix soft lockups/OOM issues w/ unix garbage collector")
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://lore.kernel.org/r/20240123170856.41348-2-kuniyu@amazon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/unix/garbage.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/unix/garbage.c b/net/unix/garbage.c
+index ab2c83d58b62a..9bfffe2a7f020 100644
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -198,7 +198,7 @@ void wait_for_unix_gc(void)
+ if (READ_ONCE(unix_tot_inflight) > UNIX_INFLIGHT_TRIGGER_GC &&
+ !READ_ONCE(gc_in_progress))
+ unix_gc();
+- wait_event(unix_gc_wait, gc_in_progress == false);
++ wait_event(unix_gc_wait, !READ_ONCE(gc_in_progress));
+ }
+
+ /* The external entry point: unix_gc() */
+--
+2.43.0
+
--- /dev/null
+From da104d480dea0889d224eb5675c7a09bfad7cfe0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Mar 2024 11:08:41 +0000
+Subject: afs: Revert "afs: Hide silly-rename files from userspace"
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 0aec3847d044273733285dcff90afda89ad461d2 ]
+
+This reverts commit 57e9d49c54528c49b8bffe6d99d782ea051ea534.
+
+This undoes the hiding of .__afsXXXX silly-rename files. The problem with
+hiding them is that rm can't then manually delete them.
+
+This also reverts commit 5f7a07646655fb4108da527565dcdc80124b14c4 ("afs: Fix
+endless loop in directory parsing") as that's a bugfix for the above.
+
+Fixes: 57e9d49c5452 ("afs: Hide silly-rename files from userspace")
+Reported-by: Markus Suvanto <markus.suvanto@gmail.com>
+Link: https://lists.infradead.org/pipermail/linux-afs/2024-February/008102.html
+Signed-off-by: David Howells <dhowells@redhat.com>
+Link: https://lore.kernel.org/r/3085695.1710328121@warthog.procyon.org.uk
+Reviewed-by: Jeffrey E Altman <jaltman@auristor.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: linux-afs@lists.infradead.org
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/afs/dir.c | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+diff --git a/fs/afs/dir.c b/fs/afs/dir.c
+index 6e2c967fae6fc..07dc4ec73520c 100644
+--- a/fs/afs/dir.c
++++ b/fs/afs/dir.c
+@@ -473,16 +473,6 @@ static int afs_dir_iterate_block(struct afs_vnode *dvnode,
+ continue;
+ }
+
+- /* Don't expose silly rename entries to userspace. */
+- if (nlen > 6 &&
+- dire->u.name[0] == '.' &&
+- ctx->actor != afs_lookup_filldir &&
+- ctx->actor != afs_lookup_one_filldir &&
+- memcmp(dire->u.name, ".__afs", 6) == 0) {
+- ctx->pos = blkoff + next * sizeof(union afs_xdr_dirent);
+- continue;
+- }
+-
+ /* found the next entry */
+ if (!dir_emit(ctx, dire->u.name, nlen,
+ ntohl(dire->u.vnode),
+--
+2.43.0
+
--- /dev/null
+From 4c5c8fe095418fa860df5e09b6b0bb6b7076760f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 Mar 2024 20:58:44 +0700
+Subject: ALSA: hda/realtek: fix ALC285 issues on HP Envy x360 laptops
+
+From: Athaariq Ardhiansyah <foss@athaariq.my.id>
+
+[ Upstream commit c062166995c9e57d5cd508b332898f79da319802 ]
+
+Realtek codec on HP Envy laptop series are heavily modified by vendor.
+Therefore, need intervention to make it work properly. The patch fixes:
+
+- B&O soundbar speakers (between lid and keyboard) activation
+- Enable LED on mute button
+- Add missing process coefficient which affects the output amplifier
+- Volume control synchronization between B&O soundbar and side speakers
+- Unmute headset output on several HP Envy models
+- Auto-enable headset mic when plugged
+
+This patch was tested on HP Envy x360 13-AR0107AU with Realtek ALC285
+
+The only unsolved problem is output amplifier of all built-in speakers
+is too weak, which causes volume of built-in speakers cannot be loud
+as vendor's proprietary driver due to missing _DSD parameter in the
+firmware. The solution is currently on research. Expected to has another
+patch in the future.
+
+Potential fix to related issues, need test before close those issues:
+
+- https://bugzilla.kernel.org/show_bug.cgi?id=189331
+- https://bugzilla.kernel.org/show_bug.cgi?id=216632
+- https://bugzilla.kernel.org/show_bug.cgi?id=216311
+- https://bugzilla.kernel.org/show_bug.cgi?id=213507
+
+Signed-off-by: Athaariq Ardhiansyah <foss@athaariq.my.id>
+Message-ID: <20240310140249.3695-1-foss@athaariq.my.id>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 63 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 63 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index ede3f8b273d79..6e759032eba2e 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -6693,6 +6693,60 @@ static void alc285_fixup_hp_spectre_x360(struct hda_codec *codec,
+ }
+ }
+
++static void alc285_fixup_hp_envy_x360(struct hda_codec *codec,
++ const struct hda_fixup *fix,
++ int action)
++{
++ static const struct coef_fw coefs[] = {
++ WRITE_COEF(0x08, 0x6a0c), WRITE_COEF(0x0d, 0xa023),
++ WRITE_COEF(0x10, 0x0320), WRITE_COEF(0x1a, 0x8c03),
++ WRITE_COEF(0x25, 0x1800), WRITE_COEF(0x26, 0x003a),
++ WRITE_COEF(0x28, 0x1dfe), WRITE_COEF(0x29, 0xb014),
++ WRITE_COEF(0x2b, 0x1dfe), WRITE_COEF(0x37, 0xfe15),
++ WRITE_COEF(0x38, 0x7909), WRITE_COEF(0x45, 0xd489),
++ WRITE_COEF(0x46, 0x00f4), WRITE_COEF(0x4a, 0x21e0),
++ WRITE_COEF(0x66, 0x03f0), WRITE_COEF(0x67, 0x1000),
++ WRITE_COEF(0x6e, 0x1005), { }
++ };
++
++ static const struct hda_pintbl pincfgs[] = {
++ { 0x12, 0xb7a60130 }, /* Internal microphone*/
++ { 0x14, 0x90170150 }, /* B&O soundbar speakers */
++ { 0x17, 0x90170153 }, /* Side speakers */
++ { 0x19, 0x03a11040 }, /* Headset microphone */
++ { }
++ };
++
++ switch (action) {
++ case HDA_FIXUP_ACT_PRE_PROBE:
++ snd_hda_apply_pincfgs(codec, pincfgs);
++
++ /* Fixes volume control problem for side speakers */
++ alc295_fixup_disable_dac3(codec, fix, action);
++
++ /* Fixes no sound from headset speaker */
++ snd_hda_codec_amp_stereo(codec, 0x21, HDA_OUTPUT, 0, -1, 0);
++
++ /* Auto-enable headset mic when plugged */
++ snd_hda_jack_set_gating_jack(codec, 0x19, 0x21);
++
++ /* Headset mic volume enhancement */
++ snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREF50);
++ break;
++ case HDA_FIXUP_ACT_INIT:
++ alc_process_coef_fw(codec, coefs);
++ break;
++ case HDA_FIXUP_ACT_BUILD:
++ rename_ctl(codec, "Bass Speaker Playback Volume",
++ "B&O-Tuned Playback Volume");
++ rename_ctl(codec, "Front Playback Switch",
++ "B&O Soundbar Playback Switch");
++ rename_ctl(codec, "Bass Speaker Playback Switch",
++ "Side Speaker Playback Switch");
++ break;
++ }
++}
++
+ /* for hda_fixup_thinkpad_acpi() */
+ #include "thinkpad_helper.c"
+
+@@ -7131,6 +7185,7 @@ enum {
+ ALC280_FIXUP_HP_9480M,
+ ALC245_FIXUP_HP_X360_AMP,
+ ALC285_FIXUP_HP_SPECTRE_X360_EB1,
++ ALC285_FIXUP_HP_ENVY_X360,
+ ALC288_FIXUP_DELL_HEADSET_MODE,
+ ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
+ ALC288_FIXUP_DELL_XPS_13,
+@@ -9054,6 +9109,12 @@ static const struct hda_fixup alc269_fixups[] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc285_fixup_hp_spectre_x360_eb1
+ },
++ [ALC285_FIXUP_HP_ENVY_X360] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = alc285_fixup_hp_envy_x360,
++ .chained = true,
++ .chain_id = ALC285_FIXUP_HP_GPIO_AMP_INIT,
++ },
+ [ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc285_fixup_ideapad_s740_coef,
+@@ -9595,6 +9656,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
+ SND_PCI_QUIRK(0x103c, 0x8519, "HP Spectre x360 15-df0xxx", ALC285_FIXUP_HP_SPECTRE_X360),
+ SND_PCI_QUIRK(0x103c, 0x8537, "HP ProBook 440 G6", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
++ SND_PCI_QUIRK(0x103c, 0x85de, "HP Envy x360 13-ar0xxx", ALC285_FIXUP_HP_ENVY_X360),
+ SND_PCI_QUIRK(0x103c, 0x860f, "HP ZBook 15 G6", ALC285_FIXUP_HP_GPIO_AMP_INIT),
+ SND_PCI_QUIRK(0x103c, 0x861f, "HP Elite Dragonfly G1", ALC285_FIXUP_HP_GPIO_AMP_INIT),
+ SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED),
+@@ -10249,6 +10311,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
+ {.id = ALC295_FIXUP_HP_OMEN, .name = "alc295-hp-omen"},
+ {.id = ALC285_FIXUP_HP_SPECTRE_X360, .name = "alc285-hp-spectre-x360"},
+ {.id = ALC285_FIXUP_HP_SPECTRE_X360_EB1, .name = "alc285-hp-spectre-x360-eb1"},
++ {.id = ALC285_FIXUP_HP_ENVY_X360, .name = "alc285-hp-envy-x360"},
+ {.id = ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP, .name = "alc287-ideapad-bass-spk-amp"},
+ {.id = ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN, .name = "alc287-yoga9-bass-spk-pin"},
+ {.id = ALC623_FIXUP_LENOVO_THINKSTATION_P340, .name = "alc623-lenovo-thinkstation-p340"},
+--
+2.43.0
+
--- /dev/null
+From 836087c16d788ce2c164b84249b07e01ba0bb062 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Feb 2024 14:53:43 +0100
+Subject: ALSA: seq: fix function cast warnings
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit d7bf73809849463f76de42aad62c850305dd6c5d ]
+
+clang-16 points out a control flow integrity (kcfi) issue when event
+callbacks get converted to incompatible types:
+
+sound/core/seq/seq_midi.c:135:30: error: cast from 'int (*)(struct snd_rawmidi_substream *, const char *, int)' to 'snd_seq_dump_func_t' (aka 'int (*)(void *, void *, int)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+ 135 | snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)dump_midi, substream);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+sound/core/seq/seq_virmidi.c:83:31: error: cast from 'int (*)(struct snd_rawmidi_substream *, const unsigned char *, int)' to 'snd_seq_dump_func_t' (aka 'int (*)(void *, void *, int)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+ 83 | snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)snd_rawmidi_receive, vmidi->substream);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For addressing those errors, introduce wrapper functions that are used
+for callbacks and bridge to the actual function call with pointer
+cast.
+
+The code was originally added with the initial ALSA merge in linux-2.5.4.
+
+[ the patch description shamelessly copied from Arnd's original patch
+ -- tiwai ]
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20240213101020.459183-1-arnd@kernel.org
+Link: https://lore.kernel.org/r/20240213135343.16411-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/core/seq/seq_midi.c | 8 +++++++-
+ sound/core/seq/seq_virmidi.c | 9 ++++++++-
+ 2 files changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
+index 4589aac091542..b00bbf18a6f5d 100644
+--- a/sound/core/seq/seq_midi.c
++++ b/sound/core/seq/seq_midi.c
+@@ -112,6 +112,12 @@ static int dump_midi(struct snd_rawmidi_substream *substream, const char *buf, i
+ return 0;
+ }
+
++/* callback for snd_seq_dump_var_event(), bridging to dump_midi() */
++static int __dump_midi(void *ptr, void *buf, int count)
++{
++ return dump_midi(ptr, buf, count);
++}
++
+ static int event_process_midi(struct snd_seq_event *ev, int direct,
+ void *private_data, int atomic, int hop)
+ {
+@@ -131,7 +137,7 @@ static int event_process_midi(struct snd_seq_event *ev, int direct,
+ pr_debug("ALSA: seq_midi: invalid sysex event flags = 0x%x\n", ev->flags);
+ return 0;
+ }
+- snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)dump_midi, substream);
++ snd_seq_dump_var_event(ev, __dump_midi, substream);
+ snd_midi_event_reset_decode(msynth->parser);
+ } else {
+ if (msynth->parser == NULL)
+diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
+index f5cae49500c81..ffd8e7202c334 100644
+--- a/sound/core/seq/seq_virmidi.c
++++ b/sound/core/seq/seq_virmidi.c
+@@ -62,6 +62,13 @@ static void snd_virmidi_init_event(struct snd_virmidi *vmidi,
+ /*
+ * decode input event and put to read buffer of each opened file
+ */
++
++/* callback for snd_seq_dump_var_event(), bridging to snd_rawmidi_receive() */
++static int dump_to_rawmidi(void *ptr, void *buf, int count)
++{
++ return snd_rawmidi_receive(ptr, buf, count);
++}
++
+ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev,
+ struct snd_seq_event *ev,
+ bool atomic)
+@@ -80,7 +87,7 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev,
+ if (ev->type == SNDRV_SEQ_EVENT_SYSEX) {
+ if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
+ continue;
+- snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)snd_rawmidi_receive, vmidi->substream);
++ snd_seq_dump_var_event(ev, dump_to_rawmidi, vmidi->substream);
+ snd_midi_event_reset_decode(vmidi->parser);
+ } else {
+ len = snd_midi_event_decode(vmidi->parser, msg, sizeof(msg), ev);
+--
+2.43.0
+
--- /dev/null
+From 948c7423f0afe0a449e8d78b51f575cf9f19ee78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Mar 2024 09:15:09 +0100
+Subject: ALSA: usb-audio: Stop parsing channels bits when all channels are
+ found.
+
+From: Johan Carlsson <johan.carlsson@teenage.engineering>
+
+[ Upstream commit a39d51ff1f52cd0b6fe7d379ac93bd8b4237d1b7 ]
+
+If a usb audio device sets more bits than the amount of channels
+it could write outside of the map array.
+
+Signed-off-by: Johan Carlsson <johan.carlsson@teenage.engineering>
+Fixes: 04324ccc75f9 ("ALSA: usb-audio: add channel map support")
+Message-ID: <20240313081509.9801-1-johan.carlsson@teenage.engineering>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/stream.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/sound/usb/stream.c b/sound/usb/stream.c
+index 3d4add94e367d..d5409f3879455 100644
+--- a/sound/usb/stream.c
++++ b/sound/usb/stream.c
+@@ -300,9 +300,12 @@ static struct snd_pcm_chmap_elem *convert_chmap(int channels, unsigned int bits,
+ c = 0;
+
+ if (bits) {
+- for (; bits && *maps; maps++, bits >>= 1)
++ for (; bits && *maps; maps++, bits >>= 1) {
+ if (bits & 1)
+ chmap->map[c++] = *maps;
++ if (c == chmap->channels)
++ break;
++ }
+ } else {
+ /* If we're missing wChannelConfig, then guess something
+ to make sure the channel map is not skipped entirely */
+--
+2.43.0
+
--- /dev/null
+From 8a9b7d4ae2e262dc03decd69d429121f539c1694 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 16:20:48 +0800
+Subject: aoe: fix the potential use-after-free problem in aoecmd_cfg_pkts
+
+From: Chun-Yi Lee <jlee@suse.com>
+
+[ Upstream commit f98364e926626c678fb4b9004b75cacf92ff0662 ]
+
+This patch is against CVE-2023-6270. The description of cve is:
+
+ A flaw was found in the ATA over Ethernet (AoE) driver in the Linux
+ kernel. The aoecmd_cfg_pkts() function improperly updates the refcnt on
+ `struct net_device`, and a use-after-free can be triggered by racing
+ between the free on the struct and the access through the `skbtxq`
+ global queue. This could lead to a denial of service condition or
+ potential code execution.
+
+In aoecmd_cfg_pkts(), it always calls dev_put(ifp) when skb initial
+code is finished. But the net_device ifp will still be used in
+later tx()->dev_queue_xmit() in kthread. Which means that the
+dev_put(ifp) should NOT be called in the success path of skb
+initial code in aoecmd_cfg_pkts(). Otherwise tx() may run into
+use-after-free because the net_device is freed.
+
+This patch removed the dev_put(ifp) in the success path in
+aoecmd_cfg_pkts(), and added dev_put() after skb xmit in tx().
+
+Link: https://nvd.nist.gov/vuln/detail/CVE-2023-6270
+Fixes: 7562f876cd93 ("[NET]: Rework dev_base via list_head (v3)")
+Signed-off-by: Chun-Yi Lee <jlee@suse.com>
+Link: https://lore.kernel.org/r/20240305082048.25526-1-jlee@suse.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/aoe/aoecmd.c | 12 ++++++------
+ drivers/block/aoe/aoenet.c | 1 +
+ 2 files changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
+index d7317425be510..cc9077b588d7e 100644
+--- a/drivers/block/aoe/aoecmd.c
++++ b/drivers/block/aoe/aoecmd.c
+@@ -419,13 +419,16 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff_head *qu
+ rcu_read_lock();
+ for_each_netdev_rcu(&init_net, ifp) {
+ dev_hold(ifp);
+- if (!is_aoe_netif(ifp))
+- goto cont;
++ if (!is_aoe_netif(ifp)) {
++ dev_put(ifp);
++ continue;
++ }
+
+ skb = new_skb(sizeof *h + sizeof *ch);
+ if (skb == NULL) {
+ printk(KERN_INFO "aoe: skb alloc failure\n");
+- goto cont;
++ dev_put(ifp);
++ continue;
+ }
+ skb_put(skb, sizeof *h + sizeof *ch);
+ skb->dev = ifp;
+@@ -440,9 +443,6 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff_head *qu
+ h->major = cpu_to_be16(aoemajor);
+ h->minor = aoeminor;
+ h->cmd = AOECMD_CFG;
+-
+-cont:
+- dev_put(ifp);
+ }
+ rcu_read_unlock();
+ }
+diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
+index 63773a90581dd..1e66c7a188a12 100644
+--- a/drivers/block/aoe/aoenet.c
++++ b/drivers/block/aoe/aoenet.c
+@@ -64,6 +64,7 @@ tx(int id) __must_hold(&txlock)
+ pr_warn("aoe: packet could not be sent on %s. %s\n",
+ ifp ? ifp->name : "netif",
+ "consider increasing tx_queue_len");
++ dev_put(ifp);
+ spin_lock_irq(&txlock);
+ }
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From b1a0d8828263b5c81d6f672a5995493eee7b5558 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Mar 2024 13:28:20 +0100
+Subject: arch/powerpc: Remove <linux/fb.h> from backlight code
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit 838f865802b9f26135ea7df4e30f89ac2f50c23e ]
+
+Replace <linux/fb.h> with a forward declaration in <asm/backlight.h> to
+resolve an unnecessary dependency. Remove pmac_backlight_curve_lookup()
+and struct fb_info from source and header files. The function and the
+framebuffer struct are unused. No functional changes.
+
+v3:
+ * Add Fixes tag (Christophe)
+ * fix typos in commit message (Jani)
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Fixes: d565dd3b0824 ("[PATCH] powerpc: More via-pmu backlight fixes")
+Reviewed-by: Jani Nikula <jani.nikula@intel.com>
+Acked-by: Michael Ellerman <mpe@ellerman.id.au> # (powerpc)
+Link: https://patchwork.freedesktop.org/patch/msgid/20240306122935.10626-4-tzimmermann@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/backlight.h | 5 ++--
+ arch/powerpc/platforms/powermac/backlight.c | 26 ---------------------
+ 2 files changed, 2 insertions(+), 29 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/backlight.h b/arch/powerpc/include/asm/backlight.h
+index 1b5eab62ed047..061a910d74929 100644
+--- a/arch/powerpc/include/asm/backlight.h
++++ b/arch/powerpc/include/asm/backlight.h
+@@ -10,15 +10,14 @@
+ #define __ASM_POWERPC_BACKLIGHT_H
+ #ifdef __KERNEL__
+
+-#include <linux/fb.h>
+ #include <linux/mutex.h>
+
++struct backlight_device;
++
+ /* For locking instructions, see the implementation file */
+ extern struct backlight_device *pmac_backlight;
+ extern struct mutex pmac_backlight_mutex;
+
+-extern int pmac_backlight_curve_lookup(struct fb_info *info, int value);
+-
+ extern int pmac_has_backlight_type(const char *type);
+
+ extern void pmac_backlight_key(int direction);
+diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c
+index aeb79a8b3e109..12bc01353bd3c 100644
+--- a/arch/powerpc/platforms/powermac/backlight.c
++++ b/arch/powerpc/platforms/powermac/backlight.c
+@@ -9,7 +9,6 @@
+ */
+
+ #include <linux/kernel.h>
+-#include <linux/fb.h>
+ #include <linux/backlight.h>
+ #include <linux/adb.h>
+ #include <linux/pmu.h>
+@@ -72,31 +71,6 @@ int pmac_has_backlight_type(const char *type)
+ return 0;
+ }
+
+-int pmac_backlight_curve_lookup(struct fb_info *info, int value)
+-{
+- int level = (FB_BACKLIGHT_LEVELS - 1);
+-
+- if (info && info->bl_dev) {
+- int i, max = 0;
+-
+- /* Look for biggest value */
+- for (i = 0; i < FB_BACKLIGHT_LEVELS; i++)
+- max = max((int)info->bl_curve[i], max);
+-
+- /* Look for nearest value */
+- for (i = 0; i < FB_BACKLIGHT_LEVELS; i++) {
+- int diff = abs(info->bl_curve[i] - value);
+- if (diff < max) {
+- max = diff;
+- level = i;
+- }
+- }
+-
+- }
+-
+- return level;
+-}
+-
+ static void pmac_backlight_key_worker(struct work_struct *work)
+ {
+ if (atomic_read(&kernel_backlight_disabled))
+--
+2.43.0
+
--- /dev/null
+From 7992d81db4594da8c3f5b7b194cf781c17ac9d19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Aug 2023 17:03:04 +0200
+Subject: ARM: dts: arm: realview: Fix development chip ROM compatible value
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 3baa4c5143d65ebab2de0d99a395e5f4f1f46608 ]
+
+When the development chip ROM was added, the "direct-mapped" compatible
+value was already obsolete. In addition, the device node lacked the
+accompanying "probe-type" property, causing the old physmap_of_core
+driver to fall back to trying all available probe types.
+Unfortunately this fallback was lost when the DT and pdata cases were
+merged.
+
+Fix this by using the modern "mtd-rom" compatible value instead.
+
+Fixes: 5c3f5edbe0a1dff3 ("ARM: realview: add flash devices to the PB1176 DTS")
+Fixes: 642b1e8dbed7bbbf ("mtd: maps: Merge physmap_of.c into physmap-core.c")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/arm-realview-pb1176.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/arm-realview-pb1176.dts b/arch/arm/boot/dts/arm-realview-pb1176.dts
+index efed325af88d2..d99bac02232b3 100644
+--- a/arch/arm/boot/dts/arm-realview-pb1176.dts
++++ b/arch/arm/boot/dts/arm-realview-pb1176.dts
+@@ -451,7 +451,7 @@ pb1176_serial3: serial@1010f000 {
+
+ /* Direct-mapped development chip ROM */
+ pb1176_rom@10200000 {
+- compatible = "direct-mapped";
++ compatible = "mtd-rom";
+ reg = <0x10200000 0x4000>;
+ bank-width = <1>;
+ };
+--
+2.43.0
+
--- /dev/null
+From 46802dc515cf81bc9f026ccb22bb885744a2bb01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Feb 2024 10:03:27 +0100
+Subject: ARM: dts: imx6dl-yapp4: Fix typo in the QCA switch register address
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michal Vokáč <michal.vokac@ysoft.com>
+
+[ Upstream commit 023bd910d3ab735459f84b22bb99fb9e00bd9d76 ]
+
+This change does not have any functional effect. The switch works just
+fine without this patch as it has full access to all the addresses
+on the bus. This is simply a clean-up to set the node name address
+and reg address to the same value.
+
+Fixes: 15b43e497ffd ("ARM: dts: imx6dl-yapp4: Use correct pseudo PHY address for the switch")
+Signed-off-by: Michal Vokáč <michal.vokac@ysoft.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6dl-yapp4-common.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi
+index cb1972f8e8d27..a655b945bf2df 100644
+--- a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi
++++ b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi
+@@ -128,7 +128,7 @@ phy_port3: phy@2 {
+
+ switch@10 {
+ compatible = "qca,qca8334";
+- reg = <10>;
++ reg = <0x10>;
+ reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
+
+ switch_ports: ports {
+--
+2.43.0
+
--- /dev/null
+From 0aa518a0b1072937855e6f9f3c4b2a4856c7b9d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Mar 2023 19:06:04 +0100
+Subject: ARM: dts: imx6dl-yapp4: Move phy reset into switch node
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michal Vokáč <michal.vokac@ysoft.com>
+
+[ Upstream commit 7da7b84fee58c85a6075022023d31edea40e81a1 ]
+
+Drop the phy-reset-duration and phy-reset-gpios deprecated properties and
+move reset-gpios under the switch node.
+
+Signed-off-by: Michal Vokáč <michal.vokac@ysoft.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Stable-dep-of: 023bd910d3ab ("ARM: dts: imx6dl-yapp4: Fix typo in the QCA switch register address")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6dl-yapp4-common.dtsi | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi
+index aacbf317feea6..cb1972f8e8d27 100644
+--- a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi
++++ b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi
+@@ -106,8 +106,6 @@ &fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-mode = "rgmii-id";
+- phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
+- phy-reset-duration = <20>;
+ phy-supply = <&sw2_reg>;
+ status = "okay";
+
+@@ -131,6 +129,7 @@ phy_port3: phy@2 {
+ switch@10 {
+ compatible = "qca,qca8334";
+ reg = <10>;
++ reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
+
+ switch_ports: ports {
+ #address-cells = <1>;
+--
+2.43.0
+
--- /dev/null
+From 56063a294a347cae5c5b471968514d9f8c45b6ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Feb 2024 10:03:28 +0100
+Subject: ARM: dts: imx6dl-yapp4: Move the internal switch PHYs under the
+ switch node
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michal Vokáč <michal.vokac@ysoft.com>
+
+[ Upstream commit 79978bff2e4b8e05ebdf5fc3ee6b794002393484 ]
+
+We identified that the PHYs actually do not work since commit 7da7b84fee58
+("ARM: dts: imx6dl-yapp4: Move phy reset into switch node") as
+a coincidence of several circumstances.
+
+The reset signal is kept asserted by a pull-down resistor on the board
+unless it is deasserted by GPIO from the SoC. This is to keep the switch
+dead until it is configured properly by the kernel and user space.
+
+Prior to the referenced commit the switch was reset by the FEC driver
+and the reset GPIO was actively deasserted. The mdio-bus was scanned
+and the attached switch and its PHYs were found and configured.
+
+With the referenced commit the switch is reset by the qca8k driver.
+Because of another bug in the qca8k driver, functionality of the reset
+pin depends on its pre-kernel configuration. See commit c44fc98f0a8f
+("net: dsa: qca8k: fix illegal usage of GPIO")
+
+The problem did not appear until we removed support for the switch
+and configuration of its reset pin from the bootloader.
+
+To fix that, properly describe the internal mdio-bus configuration of
+the qca8334 switch. The PHYs are internal to the switch and sit on its
+internal mdio-bus.
+
+Fixes: 7da7b84fee58 ("ARM: dts: imx6dl-yapp4: Move phy reset into switch node")
+Signed-off-by: Michal Vokáč <michal.vokac@ysoft.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6dl-yapp4-common.dtsi | 23 ++++++++++++++--------
+ 1 file changed, 15 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi
+index a655b945bf2df..4b7aee8958923 100644
+--- a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi
++++ b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi
+@@ -118,14 +118,6 @@ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+- phy_port2: phy@1 {
+- reg = <1>;
+- };
+-
+- phy_port3: phy@2 {
+- reg = <2>;
+- };
+-
+ switch@10 {
+ compatible = "qca,qca8334";
+ reg = <0x10>;
+@@ -150,15 +142,30 @@ fixed-link {
+ eth2: port@2 {
+ reg = <2>;
+ label = "eth2";
++ phy-mode = "internal";
+ phy-handle = <&phy_port2>;
+ };
+
+ eth1: port@3 {
+ reg = <3>;
+ label = "eth1";
++ phy-mode = "internal";
+ phy-handle = <&phy_port3>;
+ };
+ };
++
++ mdio {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ phy_port2: ethernet-phy@1 {
++ reg = <1>;
++ };
++
++ phy_port3: ethernet-phy@2 {
++ reg = <2>;
++ };
++ };
+ };
+ };
+ };
+--
+2.43.0
+
--- /dev/null
+From 9b0d8d37c0fdbf70b3ee3ab2b20b9dc9c9370a2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Feb 2024 17:45:40 +0100
+Subject: ARM: dts: qcom: msm8974: correct qfprom node size
+
+From: Craig Tatlor <ctatlor97@gmail.com>
+
+[ Upstream commit 724c4bf0e4bf81dba77736afb93964c986c3c123 ]
+
+The qfprom actually is bigger than 0x1000, so adjust the reg.
+
+Note that the non-ECC-corrected qfprom can be found at 0xfc4b8000
+(-0x4000). The current reg points to the ECC-corrected qfprom block
+which should have equivalent values at all offsets compared to the
+non-corrected version.
+
+[luca@z3ntu.xyz: extract to standalone patch and adjust for review
+comments]
+
+Fixes: c59ffb519357 ("arm: dts: msm8974: Add thermal zones, tsens and qfprom nodes")
+Signed-off-by: Craig Tatlor <ctatlor97@gmail.com>
+Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20240210-msm8974-qfprom-v3-1-26c424160334@z3ntu.xyz
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/qcom-msm8974.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
+index c4b2e9ac24940..5ea45e486ed54 100644
+--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
+@@ -1134,7 +1134,7 @@ restart@fc4ab000 {
+
+ qfprom: qfprom@fc4bc000 {
+ compatible = "qcom,msm8974-qfprom", "qcom,qfprom";
+- reg = <0xfc4bc000 0x1000>;
++ reg = <0xfc4bc000 0x2100>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ tsens_calib: calib@d0 {
+--
+2.43.0
+
--- /dev/null
+From 5bf66b882bd68044aa0a4f74cd389fc00592fdd4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jan 2024 12:03:03 +0100
+Subject: ARM: dts: renesas: r8a73a4: Fix external clocks and clock rate
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 090c4094574705b0afc7d37825cdc5d06f0e7e02 ]
+
+External clocks should be defined as zero-Hz clocks in the SoC .dtsi,
+and overridden in the board .dts when present.
+
+Correct the clock rate of extal1 from 25 to 26 MHz, to match the crystal
+oscillator present on the APE6-EVM board.
+
+Fixes: a76809a329d6ebae ("ARM: shmobile: r8a73a4: Common clock framework DT description")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Link: https://lore.kernel.org/r/1692bc8cd465d62168cbf110522ad62a7af3f606.1705315614.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/r8a73a4-ape6evm.dts | 12 ++++++++++++
+ arch/arm/boot/dts/r8a73a4.dtsi | 9 ++++++---
+ 2 files changed, 18 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/boot/dts/r8a73a4-ape6evm.dts b/arch/arm/boot/dts/r8a73a4-ape6evm.dts
+index e81a7213d3047..4282bafbb5043 100644
+--- a/arch/arm/boot/dts/r8a73a4-ape6evm.dts
++++ b/arch/arm/boot/dts/r8a73a4-ape6evm.dts
+@@ -209,6 +209,18 @@ &cmt1 {
+ status = "okay";
+ };
+
++&extal1_clk {
++ clock-frequency = <26000000>;
++};
++
++&extal2_clk {
++ clock-frequency = <48000000>;
++};
++
++&extalr_clk {
++ clock-frequency = <32768>;
++};
++
+ &pfc {
+ scifa0_pins: scifa0 {
+ groups = "scifa0_data";
+diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi
+index c39066967053f..d1f4cbd099efb 100644
+--- a/arch/arm/boot/dts/r8a73a4.dtsi
++++ b/arch/arm/boot/dts/r8a73a4.dtsi
+@@ -450,17 +450,20 @@ clocks {
+ extalr_clk: extalr {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+- clock-frequency = <32768>;
++ /* This value must be overridden by the board. */
++ clock-frequency = <0>;
+ };
+ extal1_clk: extal1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+- clock-frequency = <25000000>;
++ /* This value must be overridden by the board. */
++ clock-frequency = <0>;
+ };
+ extal2_clk: extal2 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+- clock-frequency = <48000000>;
++ /* This value must be overridden by the board. */
++ clock-frequency = <0>;
+ };
+ fsiack_clk: fsiack {
+ compatible = "fixed-clock";
+--
+2.43.0
+
--- /dev/null
+From 478e4c672e1006370a2813347e1c9899f4308807 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 Jan 2024 00:32:45 +0800
+Subject: arm64: dts: allwinner: h6: Add RX DMA channel for SPDIF
+
+From: Chen-Yu Tsai <wens@csie.org>
+
+[ Upstream commit 7b59348c11f3355e284d77bbe3d33632ddadcfc2 ]
+
+The SPDIF hardware found on the H6 supports both transmit and receive
+functions. However it is missing the RX DMA channel.
+
+Add the SPDIF hardware block's RX DMA channel. Also remove the
+by-default pinmux, since the end device can choose to implement
+either or both functionalities.
+
+Fixes: f95b598df419 ("arm64: dts: allwinner: Add SPDIF node for Allwinner H6")
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+Reviewed-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Link: https://lore.kernel.org/r/20240127163247.384439-6-wens@kernel.org
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts | 2 ++
+ arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi | 2 ++
+ arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 7 +++----
+ 3 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
+index 9ec49ac2f6fd5..381d58cea092d 100644
+--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
+@@ -291,6 +291,8 @@ sw {
+ };
+
+ &spdif {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spdif_tx_pin>;
+ status = "okay";
+ };
+
+diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi
+index 4903d6358112d..855b7d43bc503 100644
+--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi
++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi
+@@ -166,6 +166,8 @@ &r_ir {
+ };
+
+ &spdif {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spdif_tx_pin>;
+ status = "okay";
+ };
+
+diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+index ca1d287a0a01d..d11e5041bae9a 100644
+--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+@@ -406,6 +406,7 @@ spi1_cs_pin: spi1-cs-pin {
+ function = "spi1";
+ };
+
++ /omit-if-no-ref/
+ spdif_tx_pin: spdif-tx-pin {
+ pins = "PH7";
+ function = "spdif";
+@@ -655,10 +656,8 @@ spdif: spdif@5093000 {
+ clocks = <&ccu CLK_BUS_SPDIF>, <&ccu CLK_SPDIF>;
+ clock-names = "apb", "spdif";
+ resets = <&ccu RST_BUS_SPDIF>;
+- dmas = <&dma 2>;
+- dma-names = "tx";
+- pinctrl-names = "default";
+- pinctrl-0 = <&spdif_tx_pin>;
++ dmas = <&dma 2>, <&dma 2>;
++ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
+--
+2.43.0
+
--- /dev/null
+From 3f6675d143a90beea308e74cbe5b996429241d1a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jan 2024 09:49:02 +0100
+Subject: arm64: dts: imx8mm-kontron: Disable pull resistors for SD card
+ signals on BL OSM-S board
+
+From: Frieder Schrempf <frieder.schrempf@kontron.de>
+
+[ Upstream commit 5a940ba3e4d7c8710c9073ff5d0ca4644d4da9db ]
+
+Some signals have external pullup resistors on the board and don't need
+the internal ones to be enabled. Due to silicon errata ERR050080 let's
+disable the internal pull resistors whererever possible and prevent
+any unwanted behavior in case they wear out.
+
+Fixes: de9618e84f76 ("arm64: dts: Add support for Kontron SL/BL i.MX8MM OSM-S")
+Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../dts/freescale/imx8mm-kontron-bl-osm-s.dts | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts
+index 1dd03ef0a7835..d9fa0deea7002 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts
+@@ -337,40 +337,40 @@ MX8MM_IOMUXC_NAND_CE1_B_GPIO3_IO2 0x19
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+- MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190
++ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x90
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0
+- MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019
+- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
++ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19
++ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+ fsl,pins = <
+- MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194
++ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x94
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4
+- MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019
+- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
++ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19
++ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ fsl,pins = <
+- MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196
++ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x96
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6
+- MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019
+- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
++ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19
++ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0
+ >;
+ };
+ };
+--
+2.43.0
+
--- /dev/null
+From 0c74445f49aa327dec600e59b988866f246e71c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jan 2024 09:49:03 +0100
+Subject: arm64: dts: imx8mm-kontron: Disable pull resistors for SD card
+ signals on BL board
+
+From: Frieder Schrempf <frieder.schrempf@kontron.de>
+
+[ Upstream commit 008820524844326ffb3123cebceba1960c0ad0dc ]
+
+Some signals have external pullup resistors on the board and don't need
+the internal ones to be enabled. Due to silicon errata ERR050080 let's
+disable the internal pull resistors whererever possible and prevent
+any unwanted behavior in case they wear out.
+
+Fixes: 8668d8b2e67f ("arm64: dts: Add the Kontron i.MX8M Mini SoMs and baseboards")
+Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../boot/dts/freescale/imx8mm-kontron-bl.dts | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
+index bffa0ea4aa46a..d54cddd65b526 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
+@@ -314,40 +314,40 @@ MX8MM_IOMUXC_NAND_CE1_B_GPIO3_IO2 0x19
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+- MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190
++ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x90
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0
+- MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019
+- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
++ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19
++ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+ fsl,pins = <
+- MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194
++ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x94
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4
+- MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019
+- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
++ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19
++ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ fsl,pins = <
+- MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196
++ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x96
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6
+- MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019
+- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
++ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19
++ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0
+ >;
+ };
+ };
+--
+2.43.0
+
--- /dev/null
+From 95356b7cf8bad2ee207196b446c36a94cdd3bf3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jan 2024 09:48:58 +0100
+Subject: arm64: dts: imx8mm-kontron: Disable pullups for I2C signals on OSM-S
+ i.MX8MM
+
+From: Frieder Schrempf <frieder.schrempf@kontron.de>
+
+[ Upstream commit 96293af54f6aa859015d8ca40a1437d3115ad50c ]
+
+There are external pullup resistors on the board and due to silicon
+errata ERR050080 let's disable the internal ones to prevent any
+unwanted behavior in case they wear out.
+
+Fixes: de9618e84f76 ("arm64: dts: Add support for Kontron SL/BL i.MX8MM OSM-S")
+Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts | 4 ++--
+ arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts
+index 8b16bd68576c0..0730c22e5b6b9 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts
+@@ -294,8 +294,8 @@ MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2 0x19
+
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <
+- MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x400001c3
+- MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x400001c3
++ MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x40000083
++ MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x40000083
+ >;
+ };
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi
+index 8d10f5b412978..9643d6ed9a7c7 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi
+@@ -247,8 +247,8 @@ MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x19
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+- MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3
+- MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3
++ MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x40000083
++ MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x40000083
+ >;
+ };
+
+--
+2.43.0
+
--- /dev/null
+From 4b4a9e99b50526553af0b5dc57d004bac92e731b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jan 2024 09:48:59 +0100
+Subject: arm64: dts: imx8mm-kontron: Disable pullups for I2C signals on SL/BL
+ i.MX8MM
+
+From: Frieder Schrempf <frieder.schrempf@kontron.de>
+
+[ Upstream commit f19e5bb91d53264d7dac5d845a4825afadf72440 ]
+
+There are external pullup resistors on the board and due to silicon
+errata ERR050080 let's disable the internal ones to prevent any
+unwanted behavior in case they wear out.
+
+Fixes: 8668d8b2e67f ("arm64: dts: Add the Kontron i.MX8M Mini SoMs and baseboards")
+Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts | 4 ++--
+ arch/arm64/boot/dts/freescale/imx8mm-kontron-sl.dtsi | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
+index a079322a37931..8d0527bb6fa59 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
+@@ -277,8 +277,8 @@ MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2 0x19
+
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <
+- MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x400001c3
+- MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x400001c3
++ MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x40000083
++ MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x40000083
+ >;
+ };
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-sl.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-kontron-sl.dtsi
+index 0679728d24899..884ae2ad35114 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-sl.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-sl.dtsi
+@@ -237,8 +237,8 @@ MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x19
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+- MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3
+- MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3
++ MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x40000083
++ MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x40000083
+ >;
+ };
+
+--
+2.43.0
+
--- /dev/null
+From ccb3133835661082f640e0def1cfde2a7d8a8cec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jan 2024 09:49:00 +0100
+Subject: arm64: dts: imx8mm-kontron: Disable pullups for onboard UART signals
+ on BL OSM-S board
+
+From: Frieder Schrempf <frieder.schrempf@kontron.de>
+
+[ Upstream commit c6d9b5672a0e2c4b1079a50d2fc8780c40cfd3eb ]
+
+These signals are actively driven by the SoC or by the onboard
+transceiver. There's no need to enable the internal pull resistors
+and due to silicon errata ERR050080 let's disable the internal ones
+to prevent any unwanted behavior in case they wear out.
+
+Fixes: de9618e84f76 ("arm64: dts: Add support for Kontron SL/BL i.MX8MM OSM-S")
+Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../dts/freescale/imx8mm-kontron-bl-osm-s.dts | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts
+index 0730c22e5b6b9..1dd03ef0a7835 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts
+@@ -313,19 +313,19 @@ MX8MM_IOMUXC_SAI5_MCLK_GPIO3_IO25 0x19
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+- MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x140
+- MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x140
+- MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B 0x140
+- MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B 0x140
++ MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x0
++ MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x0
++ MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B 0x0
++ MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B 0x0
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+- MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x140
+- MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x140
+- MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x140
+- MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x140
++ MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x0
++ MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x0
++ MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x0
++ MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x0
+ >;
+ };
+
+--
+2.43.0
+
--- /dev/null
+From 0c8c3cdb7cda64382263661c5165cf85e286d4e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jan 2024 09:49:01 +0100
+Subject: arm64: dts: imx8mm-kontron: Disable pullups for onboard UART signals
+ on BL board
+
+From: Frieder Schrempf <frieder.schrempf@kontron.de>
+
+[ Upstream commit 162aadaa0df8217b0cc49d919dd00022fef65e78 ]
+
+These signals are actively driven by the SoC or by the onboard
+transceiver. There's no need to enable the internal pull resistors
+and due to silicon errata ERR050080 let's disable the internal ones
+to prevent any unwanted behavior in case they wear out.
+
+Fixes: 8668d8b2e67f ("arm64: dts: Add the Kontron i.MX8M Mini SoMs and baseboards")
+Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../boot/dts/freescale/imx8mm-kontron-bl.dts | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
+index 8d0527bb6fa59..bffa0ea4aa46a 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
+@@ -290,19 +290,19 @@ MX8MM_IOMUXC_SPDIF_RX_PWM2_OUT 0x19
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+- MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x140
+- MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x140
+- MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B 0x140
+- MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B 0x140
++ MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x0
++ MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x0
++ MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B 0x0
++ MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B 0x0
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+- MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x140
+- MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x140
+- MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x140
+- MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x140
++ MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x0
++ MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x0
++ MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x0
++ MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x0
+ >;
+ };
+
+--
+2.43.0
+
--- /dev/null
+From a8e0dc1dc5ffd5be0371023a9071a3c1f846dc3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jan 2024 09:49:04 +0100
+Subject: arm64: dts: imx8mm-kontron: Fix interrupt for RTC on OSM-S i.MX8MM
+ module
+
+From: Frieder Schrempf <frieder.schrempf@kontron.de>
+
+[ Upstream commit 8d0f39b7d04d864e89b84063b124fd10aa4b8809 ]
+
+The level of the interrupt signal is active low instead. Fix this.
+
+Fixes: de9618e84f76 ("arm64: dts: Add support for Kontron SL/BL i.MX8MM OSM-S")
+Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi
+index 9643d6ed9a7c7..d5199ecb3f6c1 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi
+@@ -205,7 +205,7 @@ rtc@52 {
+ reg = <0x52>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rtc>;
+- interrupts-extended = <&gpio4 1 IRQ_TYPE_LEVEL_HIGH>;
++ interrupts-extended = <&gpio4 1 IRQ_TYPE_LEVEL_LOW>;
+ trickle-diode-disable;
+ };
+ };
+--
+2.43.0
+
--- /dev/null
+From a938ef8ced8a9f97a0bbe023aa056d474b846f7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Dec 2023 15:30:46 -0800
+Subject: arm64: dts: imx8mm-venice-gw71xx: fix USB OTG VBUS
+
+From: Tim Harvey <tharvey@gateworks.com>
+
+[ Upstream commit ec2cb52fcfef5d58574f2cfbc9a99ffc20ae5a9d ]
+
+The GW71xx does not have a gpio controlled vbus regulator but it does
+require some pinctrl. Remove the regulator and move the valid pinctrl
+into the usbotg1 node.
+
+Fixes: bd306fdb4e60 ("arm64: dts: imx8mm-venice-gw71xx: fix USB OTG VBUS")
+Signed-off-by: Tim Harvey <tharvey@gateworks.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../dts/freescale/imx8mm-venice-gw71xx.dtsi | 29 ++++++-------------
+ 1 file changed, 9 insertions(+), 20 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
+index c557dbf4dcd60..2e90466db89a0 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
+@@ -47,17 +47,6 @@ pps {
+ gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+-
+- reg_usb_otg1_vbus: regulator-usb-otg1 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&pinctrl_reg_usb1_en>;
+- compatible = "regulator-fixed";
+- regulator-name = "usb_otg1_vbus";
+- gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+- enable-active-high;
+- regulator-min-microvolt = <5000000>;
+- regulator-max-microvolt = <5000000>;
+- };
+ };
+
+ /* off-board header */
+@@ -146,9 +135,10 @@ &uart3 {
+ };
+
+ &usbotg1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pinctrl_usbotg1>;
+ dr_mode = "otg";
+ over-current-active-low;
+- vbus-supply = <®_usb_otg1_vbus>;
+ status = "okay";
+ };
+
+@@ -206,14 +196,6 @@ MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x41
+ >;
+ };
+
+- pinctrl_reg_usb1_en: regusb1grp {
+- fsl,pins = <
+- MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x41
+- MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x141
+- MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x41
+- >;
+- };
+-
+ pinctrl_spi2: spi2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0xd6
+@@ -236,4 +218,11 @@ MX8MM_IOMUXC_UART3_RXD_UART3_DCE_RX 0x140
+ MX8MM_IOMUXC_UART3_TXD_UART3_DCE_TX 0x140
+ >;
+ };
++
++ pinctrl_usbotg1: usbotg1grp {
++ fsl,pins = <
++ MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x141
++ MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x41
++ >;
++ };
+ };
+--
+2.43.0
+
--- /dev/null
+From 3d1c79d89adaa696854d1ac8ff214dd69203ba4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jan 2024 13:22:58 +0100
+Subject: arm64: dts: marvell: reorder crypto interrupts on Armada SoCs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafał Miłecki <rafal@milecki.pl>
+
+[ Upstream commit ec55a22149d64f9ac41845d923b884d4a666bf4d ]
+
+Match order specified in binding documentation. It says "mem" should be
+the last interrupt.
+
+This fixes:
+arch/arm64/boot/dts/marvell/armada-3720-db.dtb: crypto@90000: interrupt-names:0: 'ring0' was expected
+ from schema $id: http://devicetree.org/schemas/crypto/inside-secure,safexcel.yaml#
+arch/arm64/boot/dts/marvell/armada-3720-db.dtb: crypto@90000: interrupt-names:1: 'ring1' was expected
+ from schema $id: http://devicetree.org/schemas/crypto/inside-secure,safexcel.yaml#
+arch/arm64/boot/dts/marvell/armada-3720-db.dtb: crypto@90000: interrupt-names:2: 'ring2' was expected
+ from schema $id: http://devicetree.org/schemas/crypto/inside-secure,safexcel.yaml#
+arch/arm64/boot/dts/marvell/armada-3720-db.dtb: crypto@90000: interrupt-names:3: 'ring3' was expected
+ from schema $id: http://devicetree.org/schemas/crypto/inside-secure,safexcel.yaml#
+arch/arm64/boot/dts/marvell/armada-3720-db.dtb: crypto@90000: interrupt-names:4: 'eip' was expected
+ from schema $id: http://devicetree.org/schemas/crypto/inside-secure,safexcel.yaml#
+arch/arm64/boot/dts/marvell/armada-3720-db.dtb: crypto@90000: interrupt-names:5: 'mem' was expected
+ from schema $id: http://devicetree.org/schemas/crypto/inside-secure,safexcel.yaml#
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 10 +++++-----
+ arch/arm64/boot/dts/marvell/armada-cp11x.dtsi | 10 +++++-----
+ 2 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+index df152c72276b8..cd28e1c45b70a 100644
+--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+@@ -426,14 +426,14 @@ xor11 {
+ crypto: crypto@90000 {
+ compatible = "inside-secure,safexcel-eip97ies";
+ reg = <0x90000 0x20000>;
+- interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
++ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "mem", "ring0", "ring1",
+- "ring2", "ring3", "eip";
++ <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "ring0", "ring1", "ring2",
++ "ring3", "eip", "mem";
+ clocks = <&nb_periph_clk 15>;
+ };
+
+diff --git a/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi b/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi
+index d6c0990a267d9..218c059b16d9c 100644
+--- a/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi
++++ b/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi
+@@ -506,14 +506,14 @@ CP11X_LABEL(sdhci0): mmc@780000 {
+ CP11X_LABEL(crypto): crypto@800000 {
+ compatible = "inside-secure,safexcel-eip197b";
+ reg = <0x800000 0x200000>;
+- interrupts = <87 IRQ_TYPE_LEVEL_HIGH>,
+- <88 IRQ_TYPE_LEVEL_HIGH>,
++ interrupts = <88 IRQ_TYPE_LEVEL_HIGH>,
+ <89 IRQ_TYPE_LEVEL_HIGH>,
+ <90 IRQ_TYPE_LEVEL_HIGH>,
+ <91 IRQ_TYPE_LEVEL_HIGH>,
+- <92 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "mem", "ring0", "ring1",
+- "ring2", "ring3", "eip";
++ <92 IRQ_TYPE_LEVEL_HIGH>,
++ <87 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "ring0", "ring1", "ring2", "ring3",
++ "eip", "mem";
+ clock-names = "core", "reg";
+ clocks = <&CP11X_LABEL(clk) 1 26>,
+ <&CP11X_LABEL(clk) 1 17>;
+--
+2.43.0
+
--- /dev/null
+From 375b09fe678dfc20aa210e1f2a67735e1186bb89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jan 2024 14:23:57 +0100
+Subject: arm64: dts: mediatek: mt7622: add missing "device_type" to memory
+ nodes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafał Miłecki <rafal@milecki.pl>
+
+[ Upstream commit 99d100e00144bc01b49a697f4bc4398f2f7e7ce4 ]
+
+This fixes:
+arch/arm64/boot/dts/mediatek/mt7622-rfb1.dtb: /: memory@40000000: 'device_type' is a required property
+ from schema $id: http://devicetree.org/schemas/memory.yaml#
+arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dtb: /: memory@40000000: 'device_type' is a required property
+ from schema $id: http://devicetree.org/schemas/memory.yaml#
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20240122132357.31264-1-zajec5@gmail.com
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts | 1 +
+ arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+index 2c35ed0734a47..b1ddc491d2936 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+@@ -74,6 +74,7 @@ led-1 {
+
+ memory@40000000 {
+ reg = <0 0x40000000 0 0x40000000>;
++ device_type = "memory";
+ };
+
+ reg_1p8v: regulator-1p8v {
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+index f9313b697ac12..527dcb279ba52 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+@@ -56,6 +56,7 @@ key-wps {
+
+ memory@40000000 {
+ reg = <0 0x40000000 0 0x20000000>;
++ device_type = "memory";
+ };
+
+ reg_1p8v: regulator-1p8v {
+--
+2.43.0
+
--- /dev/null
+From 30703c3ff692542b8d09bf0b47e8610bf9616ac8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 1 Jan 2024 19:20:40 +0100
+Subject: arm64: dts: mediatek: mt7986: add "#reset-cells" to infracfg
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rafał Miłecki <rafal@milecki.pl>
+
+[ Upstream commit d993daff5962b2dd08f32a83bb1c0e5fa75732ea ]
+
+MT7986's Infrastructure System Configuration Controller includes reset
+controller. It can reset blocks as specified in the
+include/dt-bindings/reset/mt7986-resets.h . Add #reset-cells so it can
+be referenced properly.
+
+This fixes:
+arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dtb: infracfg@10001000: '#reset-cells' is a required property
+ from schema $id: http://devicetree.org/schemas/arm/mediatek/mediatek,infracfg.yaml#
+
+Fixes: 1f9986b258c2 ("arm64: dts: mediatek: add clock support for mt7986a")
+Cc: Sam Shih <sam.shih@mediatek.com>
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Link: https://lore.kernel.org/r/20240101182040.28538-2-zajec5@gmail.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+index fc338bd497f51..108931e796465 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -110,6 +110,7 @@ infracfg: infracfg@10001000 {
+ compatible = "mediatek,mt7986-infracfg", "syscon";
+ reg = <0 0x10001000 0 0x1000>;
+ #clock-cells = <1>;
++ #reset-cells = <1>;
+ };
+
+ wed_pcie: wed-pcie@10003000 {
+--
+2.43.0
+
--- /dev/null
+From fb638ef90f41f1cad118beb73f00d160ecdd50c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Feb 2024 15:08:42 -0500
+Subject: arm64: dts: mediatek: mt8192-asurada: Remove CrosEC base detection
+ node
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit 9b49cabe631b0a25aaf8fc2ba81b5b9ea6ff01b7 ]
+
+The commit adding the ChromeOS EC to the Asurada Devicetree mistakenly
+added a base detection node. While tablet mode detection is supported by
+CrosEC and used by Hayato, it is done through the cros-ec-keyb driver.
+The base detection node, which is handled by the hid-google-hammer
+driver, also provides tablet mode detection but by checking base
+attachment status on the CrosEC, which is not supported for Asurada.
+
+Hence, remove the unused CrosEC base detection node for Asurada.
+
+Fixes: eb188a2aaa82 ("arm64: dts: mediatek: asurada: Add ChromeOS EC")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Link: https://lore.kernel.org/r/20240207-mt8192-asurada-cbas-remove-v1-1-04cb65951975@collabora.com
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
+index 50367da93cd79..c6080af1e4a30 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
+@@ -819,10 +819,6 @@ cros_ec: ec@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+- base_detection: cbas {
+- compatible = "google,cros-cbas";
+- };
+-
+ cros_ec_pwm: pwm {
+ compatible = "google,cros-ec-pwm";
+ #pwm-cells = <1>;
+--
+2.43.0
+
--- /dev/null
+From a8834a5f3066ca64b20589a8fd25aae4dff73575 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Dec 2023 13:32:42 +0200
+Subject: arm64: dts: mediatek: mt8192: fix vencoder clock name
+
+From: Eugen Hristev <eugen.hristev@collabora.com>
+
+[ Upstream commit 76aac0f2a46847ed4a7a4fdd848dd66023c19ad1 ]
+
+Clock name should be `venc_sel` as per binding.
+Fix the warning message :
+arch/arm64/boot/dts/mediatek/mt8192-asurada-hayato-r1.dtb: vcodec@17020000: clock-names:0: 'venc_sel' was expected
+ from schema $id: http://devicetree.org/schemas/media/mediatek,vcodec-encoder.yaml#
+
+Fixes: aa8f3711fc87 ("arm64: dts: mt8192: Add H264 venc device node")
+Signed-off-by: Eugen Hristev <eugen.hristev@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20231228113245.174706-4-eugen.hristev@collabora.com
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8192.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+index 2f40c6cc407c1..4ed8a0f187583 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+@@ -1539,7 +1539,7 @@ vcodec_enc: vcodec@17020000 {
+ mediatek,scp = <&scp>;
+ power-domains = <&spm MT8192_POWER_DOMAIN_VENC>;
+ clocks = <&vencsys CLK_VENC_SET1_VENC>;
+- clock-names = "venc-set1";
++ clock-names = "venc_sel";
+ assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D4>;
+ };
+--
+2.43.0
+
--- /dev/null
+From 426ee0c43fc72837529c321c42a66800a2b9301f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 May 2022 12:53:54 +0800
+Subject: arm64: dts: mt8183: kukui: Split out keyboard node and describe
+ detachables
+
+From: Hsin-Yi Wang <hsinyi@chromium.org>
+
+[ Upstream commit 82492c4ef8f65f93cd4a35c4b52518935acbb2fa ]
+
+Kukui devices krane, kodana, and kakadu use detachable keyboards, which
+only have switches to be registered.
+
+Change the keyboard node's compatible of those boards to the newly
+introduced "google,cros-ec-keyb-switches", which won't include matrix
+properties.
+
+Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
+Link: https://lore.kernel.org/r/20220527045353.2483042-1-hsinyi@chromium.org
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Stable-dep-of: 04bd6411f506 ("arm64: dts: mt8183: Move CrosEC base detection node to kukui-based DTs")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi | 2 ++
+ arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi | 6 ++++++
+ arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi | 6 ++++++
+ arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi | 6 ++++++
+ arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 1 -
+ 5 files changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
+index dccf367c7ec6c..3d95625f1b0b4 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
+@@ -4,6 +4,8 @@
+ */
+
+ #include "mt8183-kukui.dtsi"
++/* Must come after mt8183-kukui.dtsi to modify cros_ec */
++#include <arm/cros-ec-keyboard.dtsi>
+
+ / {
+ panel: panel {
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi
+index 50a0dd36b5fb3..a11adeb29b1f2 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi
+@@ -372,6 +372,12 @@ pen_eject {
+ };
+ };
+
++&cros_ec {
++ keyboard-controller {
++ compatible = "google,cros-ec-keyb-switches";
++ };
++};
++
+ &qca_wifi {
+ qcom,ath10k-calibration-variant = "GO_KAKADU";
+ };
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi
+index 06f8c80bf5536..4864c39e53a4f 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi
+@@ -339,6 +339,12 @@ touch_pin_reset: pin_reset {
+ };
+ };
+
++&cros_ec {
++ keyboard-controller {
++ compatible = "google,cros-ec-keyb-switches";
++ };
++};
++
+ &qca_wifi {
+ qcom,ath10k-calibration-variant = "GO_KODAMA";
+ };
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
+index a7b0cb3ff7b0a..d5f41c6c98814 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
+@@ -343,6 +343,12 @@ rst_pin {
+ };
+ };
+
++&cros_ec {
++ keyboard-controller {
++ compatible = "google,cros-ec-keyb-switches";
++ };
++};
++
+ &qca_wifi {
+ qcom,ath10k-calibration-variant = "LE_Krane";
+ };
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
+index a428a581c93a8..de610874a9125 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
+@@ -999,5 +999,4 @@ hub@1 {
+ };
+ };
+
+-#include <arm/cros-ec-keyboard.dtsi>
+ #include <arm/cros-ec-sbs.dtsi>
+--
+2.43.0
+
--- /dev/null
+From dfb5b1851ae1e98f83da6c82fdd646d4be8c1064 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Jan 2024 18:38:34 -0300
+Subject: arm64: dts: mt8183: Move CrosEC base detection node to kukui-based
+ DTs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit 04bd6411f506357fd1faedc2b2156e7ef206aa9a ]
+
+The cbas node is used to describe base detection functionality in the
+ChromeOS EC, which is used for units that have a detachable keyboard and
+thus rely on this functionality to switch between tablet and laptop
+mode.
+
+Despite the original commit having added the cbas node to the
+mt8183-kukui.dtsi, not all machines that include it are detachables. In
+fact all machines that include from mt8183-kukui-jacuzzi.dtsi are either
+clamshells (ie normal laptops) or convertibles, meaning the keyboard can
+be flipped but not detached. The detection for the keyboard getting
+flipped is handled by the driver bound to the keyboard-controller node
+in the EC.
+
+Move the base detection node from the base kukui dtsi to the dtsis where
+all machines are detachables, and thus actually make use of the node.
+
+Fixes: 4fa8492d1e5b ("arm64: dts: mt8183: add cbas node under cros_ec")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20240116-mt8183-kukui-cbas-remove-v3-1-055e21406e86@collabora.com
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi | 4 ++++
+ arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi | 4 ++++
+ arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi | 4 ++++
+ arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 4 ----
+ 4 files changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi
+index a11adeb29b1f2..0d3c7b8162ff0 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi
+@@ -373,6 +373,10 @@ pen_eject {
+ };
+
+ &cros_ec {
++ cbas {
++ compatible = "google,cros-cbas";
++ };
++
+ keyboard-controller {
+ compatible = "google,cros-ec-keyb-switches";
+ };
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi
+index 4864c39e53a4f..e73113cb51f53 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi
+@@ -340,6 +340,10 @@ touch_pin_reset: pin_reset {
+ };
+
+ &cros_ec {
++ cbas {
++ compatible = "google,cros-cbas";
++ };
++
+ keyboard-controller {
+ compatible = "google,cros-ec-keyb-switches";
+ };
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
+index d5f41c6c98814..181da69d18f46 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
+@@ -344,6 +344,10 @@ rst_pin {
+ };
+
+ &cros_ec {
++ cbas {
++ compatible = "google,cros-cbas";
++ };
++
+ keyboard-controller {
+ compatible = "google,cros-ec-keyb-switches";
+ };
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
+index de610874a9125..1db97d94658b9 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
+@@ -896,10 +896,6 @@ usbc_extcon: extcon0 {
+ google,usb-port-id = <0>;
+ };
+
+- cbas {
+- compatible = "google,cros-cbas";
+- };
+-
+ typec {
+ compatible = "google,cros-ec-typec";
+ #address-cells = <1>;
+--
+2.43.0
+
--- /dev/null
+From 4d28c866724026f054a1bef660786286bf4dddbe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jan 2024 07:51:57 +0000
+Subject: arm64: dts: mt8195-cherry-tomato: change watchdog reset boot flow
+
+From: Hsin-Te Yuan <yuanhsinte@google.com>
+
+[ Upstream commit ef569d5db50e7edd709e482157769a5b3c367e22 ]
+
+The external output reset signal was originally disabled and sent from
+firmware. However, an unfixed bug in the firmware on tomato prevents
+the signal from being sent, causing the device to fail to boot. To fix
+this, enable external output reset signal to allow the device to reboot
+normally.
+
+Fixes: 5eb2e303ec6b ("arm64: dts: mediatek: Introduce MT8195 Cherry platform's Tomato")
+Signed-off-by: Hsin-Te Yuan <yuanhsinte@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20240124-send-upstream-v3-1-5097c9862a73@chromium.org
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts | 4 ++++
+ arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts | 4 ++++
+ arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts | 4 ++++
+ 3 files changed, 12 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts
+index 3348ba69ff6cf..d86d193e5a75e 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts
+@@ -13,3 +13,7 @@ / {
+ &ts_10 {
+ status = "okay";
+ };
++
++&watchdog {
++ /delete-property/ mediatek,disable-extrst;
++};
+diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts
+index 4669e9d917f8c..5356f53308e24 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts
+@@ -33,3 +33,7 @@ pins-low-power-pcie0-disable {
+ &ts_10 {
+ status = "okay";
+ };
++
++&watchdog {
++ /delete-property/ mediatek,disable-extrst;
++};
+diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts
+index 5021edd02f7c1..fca3606cb951e 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts
+@@ -34,3 +34,7 @@ pins-low-power-pcie0-disable {
+ &ts_10 {
+ status = "okay";
+ };
++
++&watchdog {
++ /delete-property/ mediatek,disable-extrst;
++};
+--
+2.43.0
+
--- /dev/null
+From f0884f49e64615da0806926b5de512f963d7e08f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Dec 2023 13:39:42 +0000
+Subject: arm64: dts: qcom: msm8996: Define UFS UniPro clock limits
+
+From: Yassine Oudjana <y.oudjana@protonmail.com>
+
+[ Upstream commit 68c4c20848d71b0e69c3403becb5dd23e89e5896 ]
+
+These limits were always defined as 0, but that didn't cause any issue
+since the driver had hardcoded limits. In commit b4e13e1ae95e ("scsi: ufs:
+qcom: Add multiple frequency support for MAX_CORE_CLK_1US_CYCLES") the
+hardcoded limits were removed and the driver started reading them from DT,
+causing UFS to stop working on MSM8996. Add real UniPro clock limits to fix
+UFS.
+
+Signed-off-by: Yassine Oudjana <y.oudjana@protonmail.com>
+Fixes: 57fc67ef0d35 ("arm64: dts: qcom: msm8996: Add ufs related nodes")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20231218133917.78770-1-y.oudjana@protonmail.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8996.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+index 7400ff24e6a01..1e84791733041 100644
+--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+@@ -2021,7 +2021,7 @@ ufshc: ufshc@624000 {
+ <0 0>,
+ <0 0>,
+ <150000000 300000000>,
+- <0 0>,
++ <75000000 150000000>,
+ <0 0>,
+ <0 0>,
+ <0 0>,
+--
+2.43.0
+
--- /dev/null
+From c3679931eb04023b2fcd1babf8cf02d21d7a0386 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jan 2024 12:37:28 +0530
+Subject: arm64: dts: qcom: msm8996: Fix UFS PHY clocks
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit c83fdb4335cec507d685ba9661ed7c4ccbaf12ff ]
+
+QMP PHY used in MSM8996 requires 2 clocks:
+
+* ref - 19.2MHz reference clock from RPM
+* qref - QREF clock from GCC
+
+Fixes: 27520210e881 ("arm64: dts: qcom: msm8996: Use generic QMP driver for UFS")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20240131-ufs-phy-clock-v3-5-58a49d2f4605@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8996.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+index 789121171a110..7400ff24e6a01 100644
+--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+@@ -2043,8 +2043,8 @@ ufsphy: phy@627000 {
+ #size-cells = <1>;
+ ranges;
+
+- clocks = <&gcc GCC_UFS_CLKREF_CLK>;
+- clock-names = "ref";
++ clocks = <&rpmcc RPM_SMD_LN_BB_CLK>, <&gcc GCC_UFS_CLKREF_CLK>;
++ clock-names = "ref", "qref";
+
+ resets = <&ufshc 0>;
+ reset-names = "ufsphy";
+--
+2.43.0
+
--- /dev/null
+From 45f9888863197a39194477e0abd0c815dbc6a44a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 16:04:25 +0200
+Subject: arm64: dts: qcom: msm8998: declare VLS CLAMP register for USB3 PHY
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit fc835b2311d4deb85d776c1d73562338462aa7ac ]
+
+The USB3 PHY on the MSM8998 platform doesn't have built-in
+PCS_MISC_CLAMP_ENABLE register. Instead clamping is handled separately
+via the register in the TCSR space. Declare corresponding register.
+
+Fixes: 026dad8f5873 ("arm64: dts: qcom: msm8998: Add USB-related nodes")
+Cc: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Link: https://lore.kernel.org/r/20240117-usbc-phy-vls-clamp-v2-4-a950c223f10f@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8998.dtsi | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi
+index 6eef7cbe7d7bf..6c3aecea20370 100644
+--- a/arch/arm64/boot/dts/qcom/msm8998.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi
+@@ -1052,6 +1052,11 @@ tcsr_regs_1: syscon@1f60000 {
+ reg = <0x01f60000 0x20000>;
+ };
+
++ tcsr_regs_2: syscon@1fc0000 {
++ compatible = "qcom,msm8998-tcsr", "syscon";
++ reg = <0x01fc0000 0x26000>;
++ };
++
+ tlmm: pinctrl@3400000 {
+ compatible = "qcom,msm8998-pinctrl";
+ reg = <0x03400000 0xc00000>;
+@@ -2058,6 +2063,8 @@ usb3phy: phy@c010000 {
+ reset-names = "phy",
+ "phy_phy";
+
++ qcom,tcsr-reg = <&tcsr_regs_2 0xb244>;
++
+ status = "disabled";
+ };
+
+--
+2.43.0
+
--- /dev/null
+From 7f332397f1362014e3f65f27a9e8ef7f5215c4e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jan 2024 12:37:29 +0530
+Subject: arm64: dts: qcom: msm8998: Fix UFS PHY clocks
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 5e653a7ff4426242f22dd8bc6af7f29e10ee0d68 ]
+
+QMP PHY used in MSM8998 requires 3 clocks:
+
+* ref - 19.2MHz reference clock from RPM
+* ref_aux - Auxiliary reference clock from GCC
+* qref - QREF clock from GCC
+
+Fixes: cd3dbe2a4e6c ("arm64: dts: qcom: msm8998: Add UFS nodes")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20240131-ufs-phy-clock-v3-6-58a49d2f4605@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8998.dtsi | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi
+index 6c3aecea20370..fd81b62c35776 100644
+--- a/arch/arm64/boot/dts/qcom/msm8998.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi
+@@ -1021,12 +1021,12 @@ ufsphy: phy@1da7000 {
+ status = "disabled";
+ ranges;
+
+- clock-names =
+- "ref",
+- "ref_aux";
+- clocks =
+- <&gcc GCC_UFS_CLKREF_CLK>,
+- <&gcc GCC_UFS_PHY_AUX_CLK>;
++ clocks = <&rpmcc RPM_SMD_LN_BB_CLK1>,
++ <&gcc GCC_UFS_PHY_AUX_CLK>,
++ <&gcc GCC_UFS_CLKREF_CLK>;
++ clock-names = "ref",
++ "ref_aux",
++ "qref";
+
+ reset-names = "ufsphy";
+ resets = <&ufshc 0>;
+--
+2.43.0
+
--- /dev/null
+From 4c1be7016ee67867542f5dc20b761416b4a49b60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Aug 2023 00:19:46 +0300
+Subject: arm64: dts: qcom: msm8998: switch USB QMP PHY to new style of
+ bindings
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit b7efebfeb2e8ad8187cdabba5f0212ba2e6c1069 ]
+
+Change the USB QMP PHY to use newer style of QMP PHY bindings (single
+resource region, no per-PHY subnodes).
+
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20230824211952.1397699-11-dmitry.baryshkov@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: fc835b2311d4 ("arm64: dts: qcom: msm8998: declare VLS CLAMP register for USB3 PHY")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/msm8998.dtsi | 35 +++++++++++----------------
+ 1 file changed, 14 insertions(+), 21 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi
+index 7a41250539ff5..6eef7cbe7d7bf 100644
+--- a/arch/arm64/boot/dts/qcom/msm8998.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi
+@@ -2030,7 +2030,7 @@ usb3_dwc3: usb@a800000 {
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+ snps,dis_u2_susphy_quirk;
+ snps,dis_enblslpm_quirk;
+- phys = <&qusb2phy>, <&usb1_ssphy>;
++ phys = <&qusb2phy>, <&usb3phy>;
+ phy-names = "usb2-phy", "usb3-phy";
+ snps,has-lpm-erratum;
+ snps,hird-threshold = /bits/ 8 <0x10>;
+@@ -2039,33 +2039,26 @@ usb3_dwc3: usb@a800000 {
+
+ usb3phy: phy@c010000 {
+ compatible = "qcom,msm8998-qmp-usb3-phy";
+- reg = <0x0c010000 0x18c>;
+- status = "disabled";
+- #address-cells = <1>;
+- #size-cells = <1>;
+- ranges;
++ reg = <0x0c010000 0x1000>;
+
+ clocks = <&gcc GCC_USB3_PHY_AUX_CLK>,
++ <&gcc GCC_USB3_CLKREF_CLK>,
+ <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
+- <&gcc GCC_USB3_CLKREF_CLK>;
+- clock-names = "aux", "cfg_ahb", "ref";
++ <&gcc GCC_USB3_PHY_PIPE_CLK>;
++ clock-names = "aux",
++ "ref",
++ "cfg_ahb",
++ "pipe";
++ clock-output-names = "usb3_phy_pipe_clk_src";
++ #clock-cells = <0>;
++ #phy-cells = <0>;
+
+ resets = <&gcc GCC_USB3_PHY_BCR>,
+ <&gcc GCC_USB3PHY_PHY_BCR>;
+- reset-names = "phy", "common";
++ reset-names = "phy",
++ "phy_phy";
+
+- usb1_ssphy: phy@c010200 {
+- reg = <0xc010200 0x128>,
+- <0xc010400 0x200>,
+- <0xc010c00 0x20c>,
+- <0xc010600 0x128>,
+- <0xc010800 0x200>;
+- #phy-cells = <0>;
+- #clock-cells = <0>;
+- clocks = <&gcc GCC_USB3_PHY_PIPE_CLK>;
+- clock-names = "pipe0";
+- clock-output-names = "usb3_phy_pipe_clk_src";
+- };
++ status = "disabled";
+ };
+
+ qusb2phy: phy@c012000 {
+--
+2.43.0
+
--- /dev/null
+From 1154c3a467b6aa7ffbef75370e18c4c3cfff3141 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jan 2024 12:37:37 +0530
+Subject: arm64: dts: qcom: sc8280xp: Fix UFS PHY clocks
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 1d4ef9644e219202ed89ac42f3e1defebcab9c7d ]
+
+QMP PHY used in SC8280XP requires 3 clocks:
+
+* ref - 19.2MHz reference clock from RPMh
+* ref_aux - Auxiliary reference clock from GCC
+* qref - QREF clock from GCC
+
+Fixes: 152d1faf1e2f ("arm64: dts: qcom: add SC8280XP platform")
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20240131-ufs-phy-clock-v3-14-58a49d2f4605@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sc8280xp.dtsi | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+index 88140ce104a44..57937fdd1e790 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+@@ -889,9 +889,12 @@ ufs_mem_phy: phy@1d87000 {
+ compatible = "qcom,sc8280xp-qmp-ufs-phy";
+ reg = <0 0x01d87000 0 0x1000>;
+
+- clocks = <&gcc GCC_UFS_CARD_CLKREF_CLK>,
+- <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
+- clock-names = "ref", "ref_aux";
++ clocks = <&rpmhcc RPMH_CXO_CLK>,
++ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
++ <&gcc GCC_UFS_CARD_CLKREF_CLK>;
++ clock-names = "ref",
++ "ref_aux",
++ "qref";
+
+ power-domains = <&gcc UFS_PHY_GDSC>;
+
+@@ -951,9 +954,12 @@ ufs_card_phy: phy@1da7000 {
+ compatible = "qcom,sc8280xp-qmp-ufs-phy";
+ reg = <0 0x01da7000 0 0x1000>;
+
+- clocks = <&gcc GCC_UFS_1_CARD_CLKREF_CLK>,
+- <&gcc GCC_UFS_CARD_PHY_AUX_CLK>;
+- clock-names = "ref", "ref_aux";
++ clocks = <&rpmhcc RPMH_CXO_CLK>,
++ <&gcc GCC_UFS_CARD_PHY_AUX_CLK>,
++ <&gcc GCC_UFS_1_CARD_CLKREF_CLK>;
++ clock-names = "ref",
++ "ref_aux",
++ "qref";
+
+ power-domains = <&gcc UFS_CARD_GDSC>;
+
+--
+2.43.0
+
--- /dev/null
+From af01b2e4bf1cbd26902e27b2e68222d142ba287a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Nov 2022 10:20:45 +0100
+Subject: arm64: dts: qcom: sc8280xp: update UFS PHY nodes
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit 33c4e6588e4f018abc43381ee21fe2bed37e34a5 ]
+
+Update the UFS PHY nodes to match the new binding.
+
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Reviewed-by: Brian Masney <bmasney@redhat.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@somainline.org>
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20221104092045.17410-3-johan+linaro@kernel.org
+Stable-dep-of: 1d4ef9644e21 ("arm64: dts: qcom: sc8280xp: Fix UFS PHY clocks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sc8280xp.dtsi | 49 +++++++++-----------------
+ 1 file changed, 17 insertions(+), 32 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+index 7e3aaf5de3f5c..88140ce104a44 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+@@ -845,7 +845,7 @@ ufs_mem_hc: ufs@1d84000 {
+ "jedec,ufs-2.0";
+ reg = <0 0x01d84000 0 0x3000>;
+ interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
+- phys = <&ufs_mem_phy_lanes>;
++ phys = <&ufs_mem_phy>;
+ phy-names = "ufsphy";
+ lanes-per-direction = <2>;
+ #reset-cells = <1>;
+@@ -887,27 +887,20 @@ ufs_mem_hc: ufs@1d84000 {
+
+ ufs_mem_phy: phy@1d87000 {
+ compatible = "qcom,sc8280xp-qmp-ufs-phy";
+- reg = <0 0x01d87000 0 0x1c8>;
+- #address-cells = <2>;
+- #size-cells = <2>;
+- ranges;
+- clock-names = "ref",
+- "ref_aux";
++ reg = <0 0x01d87000 0 0x1000>;
++
+ clocks = <&gcc GCC_UFS_CARD_CLKREF_CLK>,
+ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
++ clock-names = "ref", "ref_aux";
++
++ power-domains = <&gcc UFS_PHY_GDSC>;
+
+ resets = <&ufs_mem_hc 0>;
+ reset-names = "ufsphy";
+- status = "disabled";
+
+- ufs_mem_phy_lanes: phy@1d87400 {
+- reg = <0 0x01d87400 0 0x108>,
+- <0 0x01d87600 0 0x1e0>,
+- <0 0x01d87c00 0 0x1dc>,
+- <0 0x01d87800 0 0x108>,
+- <0 0x01d87a00 0 0x1e0>;
+- #phy-cells = <0>;
+- };
++ #phy-cells = <0>;
++
++ status = "disabled";
+ };
+
+ ufs_card_hc: ufs@1da4000 {
+@@ -915,7 +908,7 @@ ufs_card_hc: ufs@1da4000 {
+ "jedec,ufs-2.0";
+ reg = <0 0x01da4000 0 0x3000>;
+ interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+- phys = <&ufs_card_phy_lanes>;
++ phys = <&ufs_card_phy>;
+ phy-names = "ufsphy";
+ lanes-per-direction = <2>;
+ #reset-cells = <1>;
+@@ -956,28 +949,20 @@ ufs_card_hc: ufs@1da4000 {
+
+ ufs_card_phy: phy@1da7000 {
+ compatible = "qcom,sc8280xp-qmp-ufs-phy";
+- reg = <0 0x01da7000 0 0x1c8>;
+- #address-cells = <2>;
+- #size-cells = <2>;
+- ranges;
+- clock-names = "ref",
+- "ref_aux";
++ reg = <0 0x01da7000 0 0x1000>;
++
+ clocks = <&gcc GCC_UFS_1_CARD_CLKREF_CLK>,
+ <&gcc GCC_UFS_CARD_PHY_AUX_CLK>;
++ clock-names = "ref", "ref_aux";
++
++ power-domains = <&gcc UFS_CARD_GDSC>;
+
+ resets = <&ufs_card_hc 0>;
+ reset-names = "ufsphy";
+
+- status = "disabled";
++ #phy-cells = <0>;
+
+- ufs_card_phy_lanes: phy@1da7400 {
+- reg = <0 0x01da7400 0 0x108>,
+- <0 0x01da7600 0 0x1e0>,
+- <0 0x01da7c00 0 0x1dc>,
+- <0 0x01da7800 0 0x108>,
+- <0 0x01da7a00 0 0x1e0>;
+- #phy-cells = <0>;
+- };
++ status = "disabled";
+ };
+
+ tcsr_mutex: hwlock@1f40000 {
+--
+2.43.0
+
--- /dev/null
+From 3b66b215ade88d09d987d31f77c504251f0cddad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jan 2024 14:12:15 +0100
+Subject: arm64: dts: qcom: sdm845-db845c: correct PCIe wake-gpios
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 584a327c5cffc36369b2a8953d9448826240f1ac ]
+
+Bindings allow a "wake", not "enable", GPIO. Schematics also use WAKE
+name for the pin:
+
+ sdm845-db845c.dtb: pcie@1c00000: Unevaluated properties are not allowed ('enable-gpio' was unexpected)
+
+Fixes: 4a657c264b78 ("arm64: dts: qcom: db845c: Enable PCIe controllers")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20240108131216.53867-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+index 135ff4368c4a6..5c04c91b0ee2b 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+@@ -532,7 +532,7 @@ &mss_pil {
+ &pcie0 {
+ status = "okay";
+ perst-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>;
+- enable-gpio = <&tlmm 134 GPIO_ACTIVE_HIGH>;
++ wake-gpios = <&tlmm 134 GPIO_ACTIVE_HIGH>;
+
+ vddpe-3v3-supply = <&pcie0_3p3v_dual>;
+
+--
+2.43.0
+
--- /dev/null
+From b351fbd5629067255d82687b9d71be5fb2b658a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jan 2024 12:37:30 +0530
+Subject: arm64: dts: qcom: sdm845: Fix UFS PHY clocks
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit ca8fb2bd2248ae05890c011d691ba5d4a1e7d8d6 ]
+
+QMP PHY used in SDM845 requires 3 clocks:
+
+* ref - 19.2MHz reference clock from RPMh
+* ref_aux - Auxiliary reference clock from GCC
+* qref - QREF clock from GCC
+
+While at it, let's move 'clocks' property before 'clock-names' to match
+the style used commonly.
+
+Fixes: cc16687fbd74 ("arm64: dts: qcom: sdm845: add UFS controller")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20240131-ufs-phy-clock-v3-7-58a49d2f4605@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm845.dtsi | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
+index 8d2c78083ee49..b613c58bb43b6 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
+@@ -2530,10 +2530,12 @@ ufs_mem_phy: phy@1d87000 {
+ compatible = "qcom,sdm845-qmp-ufs-phy";
+ reg = <0 0x01d87000 0 0x1000>;
+
++ clocks = <&rpmhcc RPMH_CXO_CLK>,
++ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
++ <&gcc GCC_UFS_MEM_CLKREF_CLK>;
+ clock-names = "ref",
+- "ref_aux";
+- clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>,
+- <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
++ "ref_aux",
++ "qref";
+
+ resets = <&ufs_mem_hc 0>;
+ reset-names = "ufsphy";
+--
+2.43.0
+
--- /dev/null
+From 301cb837db13f05e1efa924dabd48c840849e4b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 06:25:46 +0300
+Subject: arm64: dts: qcom: sdm845: switch UFS QMP PHY to new style of bindings
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 760baba5e79bae651c59df89d441fad2bd0be4a5 ]
+
+Change the UFS QMP PHY to use newer style of QMP PHY bindings (single
+resource region, no per-PHY subnodes).
+
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20231205032552.1583336-4-dmitry.baryshkov@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: ca8fb2bd2248 ("arm64: dts: qcom: sdm845: Fix UFS PHY clocks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sdm845.dtsi | 19 +++++--------------
+ 1 file changed, 5 insertions(+), 14 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
+index 95c515da9f2e0..8d2c78083ee49 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
+@@ -2482,7 +2482,7 @@ ufs_mem_hc: ufshc@1d84000 {
+ <0 0x01d90000 0 0x8000>;
+ reg-names = "std", "ice";
+ interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
+- phys = <&ufs_mem_phy_lanes>;
++ phys = <&ufs_mem_phy>;
+ phy-names = "ufsphy";
+ lanes-per-direction = <2>;
+ power-domains = <&gcc UFS_PHY_GDSC>;
+@@ -2528,10 +2528,8 @@ ufs_mem_hc: ufshc@1d84000 {
+
+ ufs_mem_phy: phy@1d87000 {
+ compatible = "qcom,sdm845-qmp-ufs-phy";
+- reg = <0 0x01d87000 0 0x18c>;
+- #address-cells = <2>;
+- #size-cells = <2>;
+- ranges;
++ reg = <0 0x01d87000 0 0x1000>;
++
+ clock-names = "ref",
+ "ref_aux";
+ clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>,
+@@ -2539,16 +2537,9 @@ ufs_mem_phy: phy@1d87000 {
+
+ resets = <&ufs_mem_hc 0>;
+ reset-names = "ufsphy";
+- status = "disabled";
+
+- ufs_mem_phy_lanes: phy@1d87400 {
+- reg = <0 0x01d87400 0 0x108>,
+- <0 0x01d87600 0 0x1e0>,
+- <0 0x01d87c00 0 0x1dc>,
+- <0 0x01d87800 0 0x108>,
+- <0 0x01d87a00 0 0x1e0>;
+- #phy-cells = <0>;
+- };
++ #phy-cells = <0>;
++ status = "disabled";
+ };
+
+ cryptobam: dma-controller@1dc4000 {
+--
+2.43.0
+
--- /dev/null
+From 6c20efa3e7ee478fe125ad0914ac67d284577690 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jan 2024 12:37:33 +0530
+Subject: arm64: dts: qcom: sm6350: Fix UFS PHY clocks
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 68f9fcba3a0c015d649907805534fe66c9c60865 ]
+
+QMP PHY used in SM6350 requires 3 clocks:
+
+* ref - 19.2MHz reference clock from RPMh
+* ref_aux - Auxiliary reference clock from GCC
+* qref - QREF clock from GCC
+
+While at it, let's move 'clocks' property before 'clock-names' to match
+the style used commonly.
+
+Fixes: 5a814af5fc22 ("arm64: dts: qcom: sm6350: Add UFS nodes")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20240131-ufs-phy-clock-v3-10-58a49d2f4605@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm6350.dtsi | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi
+index 9da373090593c..3f6817a3ee877 100644
+--- a/arch/arm64/boot/dts/qcom/sm6350.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi
+@@ -825,10 +825,12 @@ ufs_mem_phy: phy@1d87000 {
+ #size-cells = <2>;
+ ranges;
+
++ clocks = <&rpmhcc RPMH_CXO_CLK>,
++ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
++ <&gcc GCC_UFS_MEM_CLKREF_CLK>;
+ clock-names = "ref",
+- "ref_aux";
+- clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>,
+- <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
++ "ref_aux",
++ "qref";
+
+ resets = <&ufs_mem_hc 0>;
+ reset-names = "ufsphy";
+--
+2.43.0
+
--- /dev/null
+From 5139912353210ddaea4d0d592b5963ce25b6997b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jan 2024 14:12:16 +0100
+Subject: arm64: dts: qcom: sm8150: correct PCIe wake-gpios
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 7c38989d0f7a35c83e7c4781271d42662903fa8d ]
+
+Bindings allow a "wake", not "enable", GPIO. Schematics also use WAKE
+name for the pin:
+
+ sa8155p-adp.dtb: pcie@1c00000: Unevaluated properties are not allowed ('enable-gpio' was unexpected)
+
+Fixes: a1c86c680533 ("arm64: dts: qcom: sm8150: Add PCIe nodes")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20240108131216.53867-2-krzysztof.kozlowski@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8150.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+index 2734886831f4d..72e8d73628389 100644
+--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+@@ -1823,7 +1823,7 @@ pcie0: pci@1c00000 {
+ phy-names = "pciephy";
+
+ perst-gpios = <&tlmm 35 GPIO_ACTIVE_HIGH>;
+- enable-gpio = <&tlmm 37 GPIO_ACTIVE_HIGH>;
++ wake-gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie0_default_state>;
+--
+2.43.0
+
--- /dev/null
+From e30bcdf7fcb554f69bb94045f5eb38372c67c018 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jan 2024 12:37:34 +0530
+Subject: arm64: dts: qcom: sm8150: Fix UFS PHY clocks
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit eff7496b72810ca54da8c9c4542bf2aca479dd44 ]
+
+QMP PHY used in SM8150 requires 3 clocks:
+
+* ref - 19.2MHz reference clock from RPMh
+* ref_aux - Auxiliary reference clock from GCC
+* qref - QREF clock from GCC
+
+While at it, let's move 'clocks' property before 'clock-names' to match
+the style used commonly.
+
+Fixes: 3834a2e92229 ("arm64: dts: qcom: sm8150: Add ufs nodes")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20240131-ufs-phy-clock-v3-11-58a49d2f4605@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8150.dtsi | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+index 0c2981feb3c8c..1b7a26c55331c 100644
+--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+@@ -2026,10 +2026,12 @@ ufs_mem_phy: phy@1d87000 {
+ compatible = "qcom,sm8150-qmp-ufs-phy";
+ reg = <0 0x01d87000 0 0x1000>;
+
++ clocks = <&rpmhcc RPMH_CXO_CLK>,
++ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
++ <&gcc GCC_UFS_MEM_CLKREF_CLK>;
+ clock-names = "ref",
+- "ref_aux";
+- clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>,
+- <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
++ "ref_aux",
++ "qref";
+
+ power-domains = <&gcc UFS_PHY_GDSC>;
+
+--
+2.43.0
+
--- /dev/null
+From 7a3c8fb2a959dcc36ec3602323bdad07cdcfe960 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 06:25:49 +0300
+Subject: arm64: dts: qcom: sm8150: switch UFS QMP PHY to new style of bindings
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit 935c76f7f85912962d72eceabdfa2c38c4c07f02 ]
+
+Change the UFS QMP PHY to use newer style of QMP PHY bindings (single
+resource region, no per-PHY subnodes).
+
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20231205032552.1583336-7-dmitry.baryshkov@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: eff7496b7281 ("arm64: dts: qcom: sm8150: Fix UFS PHY clocks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8150.dtsi | 20 ++++++--------------
+ 1 file changed, 6 insertions(+), 14 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+index eb1a9369926d2..0c2981feb3c8c 100644
+--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+@@ -1979,7 +1979,7 @@ ufs_mem_hc: ufshc@1d84000 {
+ <0 0x01d90000 0 0x8000>;
+ reg-names = "std", "ice";
+ interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
+- phys = <&ufs_mem_phy_lanes>;
++ phys = <&ufs_mem_phy>;
+ phy-names = "ufsphy";
+ lanes-per-direction = <2>;
+ #reset-cells = <1>;
+@@ -2024,10 +2024,8 @@ ufs_mem_hc: ufshc@1d84000 {
+
+ ufs_mem_phy: phy@1d87000 {
+ compatible = "qcom,sm8150-qmp-ufs-phy";
+- reg = <0 0x01d87000 0 0x1c0>;
+- #address-cells = <2>;
+- #size-cells = <2>;
+- ranges;
++ reg = <0 0x01d87000 0 0x1000>;
++
+ clock-names = "ref",
+ "ref_aux";
+ clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>,
+@@ -2037,16 +2035,10 @@ ufs_mem_phy: phy@1d87000 {
+
+ resets = <&ufs_mem_hc 0>;
+ reset-names = "ufsphy";
+- status = "disabled";
+
+- ufs_mem_phy_lanes: phy@1d87400 {
+- reg = <0 0x01d87400 0 0x16c>,
+- <0 0x01d87600 0 0x200>,
+- <0 0x01d87c00 0 0x200>,
+- <0 0x01d87800 0 0x16c>,
+- <0 0x01d87a00 0 0x200>;
+- #phy-cells = <0>;
+- };
++ #phy-cells = <0>;
++
++ status = "disabled";
+ };
+
+ ipa_virt: interconnect@1e00000 {
+--
+2.43.0
+
--- /dev/null
+From 3f93e61671b47d15b6a3517baf13af7d6b5f6f84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Nov 2023 17:42:26 +0100
+Subject: arm64: dts: qcom: sm8150: use 'gpios' suffix for PCI GPIOs
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit af6f6778d34cb40e60368e288767f674cc0c5f60 ]
+
+Linux handles both versions, but bindings expect GPIO properties to
+have 'gpios' suffix instead of 'gpio':
+
+ sa8155p-adp.dtb: pci@1c00000: Unevaluated properties are not allowed ('perst-gpio' was unexpected)
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20231111164229.63803-3-krzysztof.kozlowski@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: 7c38989d0f7a ("arm64: dts: qcom: sm8150: correct PCIe wake-gpios")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8150.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+index 1b7a26c55331c..2734886831f4d 100644
+--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+@@ -1822,7 +1822,7 @@ pcie0: pci@1c00000 {
+ phys = <&pcie0_lane>;
+ phy-names = "pciephy";
+
+- perst-gpio = <&tlmm 35 GPIO_ACTIVE_HIGH>;
++ perst-gpios = <&tlmm 35 GPIO_ACTIVE_HIGH>;
+ enable-gpio = <&tlmm 37 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-names = "default";
+@@ -1925,7 +1925,7 @@ pcie1: pci@1c08000 {
+ phys = <&pcie1_lane>;
+ phy-names = "pciephy";
+
+- perst-gpio = <&tlmm 102 GPIO_ACTIVE_HIGH>;
++ perst-gpios = <&tlmm 102 GPIO_ACTIVE_HIGH>;
+ enable-gpio = <&tlmm 104 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-names = "default";
+--
+2.43.0
+
--- /dev/null
+From 8af5a30adf728eb5158b357e245e4e2957196e23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jan 2024 12:37:35 +0530
+Subject: arm64: dts: qcom: sm8250: Fix UFS PHY clocks
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 55ee02b10bdd9577b6eabe98ebb383ec4e0674a7 ]
+
+QMP PHY used in SM8250 requires 3 clocks:
+
+* ref - 19.2MHz reference clock from RPMh
+* ref_aux - Auxiliary reference clock from GCC
+* qref - QREF clock from GCC
+
+While at it, let's move 'clocks' property before 'clock-names' to match
+the style used commonly.
+
+Fixes: b7e2fba06622 ("arm64: dts: qcom: sm8250: Add UFS controller and PHY")
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20240131-ufs-phy-clock-v3-12-58a49d2f4605@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8250.dtsi | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+index 194fb00051d66..30f00989bfcdc 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+@@ -2171,10 +2171,12 @@ ufs_mem_phy: phy@1d87000 {
+ compatible = "qcom,sm8250-qmp-ufs-phy";
+ reg = <0 0x01d87000 0 0x1000>;
+
+- clock-names = "ref",
+- "ref_aux";
+ clocks = <&rpmhcc RPMH_CXO_CLK>,
+- <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
++ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
++ <&gcc GCC_UFS_1X_CLKREF_EN>;
++ clock-names = "ref",
++ "ref_aux",
++ "qref";
+
+ resets = <&ufs_mem_hc 0>;
+ reset-names = "ufsphy";
+--
+2.43.0
+
--- /dev/null
+From 566ddfe20e0225d7f2e05cee0446b313965a46bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 06:25:50 +0300
+Subject: arm64: dts: qcom: sm8250: switch UFS QMP PHY to new style of bindings
+
+From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+
+[ Upstream commit ba865bdcc688932980b8e5ec2154eaa33cd4a981 ]
+
+Change the UFS QMP PHY to use newer style of QMP PHY bindings (single
+resource region, no per-PHY subnodes).
+
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20231205032552.1583336-8-dmitry.baryshkov@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: 55ee02b10bdd ("arm64: dts: qcom: sm8250: Fix UFS PHY clocks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8250.dtsi | 20 ++++++--------------
+ 1 file changed, 6 insertions(+), 14 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+index 3d02adbc0b62f..194fb00051d66 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+@@ -2125,7 +2125,7 @@ ufs_mem_hc: ufshc@1d84000 {
+ "jedec,ufs-2.0";
+ reg = <0 0x01d84000 0 0x3000>;
+ interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
+- phys = <&ufs_mem_phy_lanes>;
++ phys = <&ufs_mem_phy>;
+ phy-names = "ufsphy";
+ lanes-per-direction = <2>;
+ #reset-cells = <1>;
+@@ -2169,10 +2169,8 @@ ufs_mem_hc: ufshc@1d84000 {
+
+ ufs_mem_phy: phy@1d87000 {
+ compatible = "qcom,sm8250-qmp-ufs-phy";
+- reg = <0 0x01d87000 0 0x1c0>;
+- #address-cells = <2>;
+- #size-cells = <2>;
+- ranges;
++ reg = <0 0x01d87000 0 0x1000>;
++
+ clock-names = "ref",
+ "ref_aux";
+ clocks = <&rpmhcc RPMH_CXO_CLK>,
+@@ -2180,16 +2178,10 @@ ufs_mem_phy: phy@1d87000 {
+
+ resets = <&ufs_mem_hc 0>;
+ reset-names = "ufsphy";
+- status = "disabled";
+
+- ufs_mem_phy_lanes: phy@1d87400 {
+- reg = <0 0x01d87400 0 0x16c>,
+- <0 0x01d87600 0 0x200>,
+- <0 0x01d87c00 0 0x200>,
+- <0 0x01d87800 0 0x16c>,
+- <0 0x01d87a00 0 0x200>;
+- #phy-cells = <0>;
+- };
++ #phy-cells = <0>;
++
++ status = "disabled";
+ };
+
+ ipa_virt: interconnect@1e00000 {
+--
+2.43.0
+
--- /dev/null
+From 6d1573b1421afd516dc82d161f8c6f15ea93711f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Feb 2024 15:21:30 +0100
+Subject: arm64: dts: renesas: r8a779a0: Correct avb[01] reg sizes
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 0c51912331f8ba5ce5fb52f46e340945160672a3 ]
+
+All Ethernet AVB instances on R-Car V3U have registers related to UDP/IP
+support, but the declared register blocks for the first two instances
+are too small to cover them.
+
+Fix this by extending the register block sizes.
+
+Fixes: 5a633320f08b8c9b ("arm64: dts: renesas: r8a779a0: Add Ethernet-AVB support")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/ce6ce3c4b1495e02e7c1803fca810a7178a84500.1707660323.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/renesas/r8a779a0.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
+index 41fbb9998cf82..b677ef6705d94 100644
+--- a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
+@@ -657,7 +657,7 @@ channel7 {
+ avb0: ethernet@e6800000 {
+ compatible = "renesas,etheravb-r8a779a0",
+ "renesas,etheravb-rcar-gen4";
+- reg = <0 0xe6800000 0 0x800>;
++ reg = <0 0xe6800000 0 0x1000>;
+ interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
+@@ -705,7 +705,7 @@ avb0: ethernet@e6800000 {
+ avb1: ethernet@e6810000 {
+ compatible = "renesas,etheravb-r8a779a0",
+ "renesas,etheravb-rcar-gen4";
+- reg = <0 0xe6810000 0 0x800>;
++ reg = <0 0xe6810000 0 0x1000>;
+ interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
+--
+2.43.0
+
--- /dev/null
+From d21748dad6e8ffae7d45124b1168129c307b3ccd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Oct 2022 12:03:52 +0200
+Subject: arm64: dts: renesas: r8a779a0: Update to R-Car Gen4 compatible values
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit a1ca409cc050166a9e8ed183c1d4192f511cf6a2 ]
+
+Despite the name, R-Car V3U is the first member of the R-Car Gen4
+family. Hence update the compatible properties in various device nodes
+to include family-specific compatible values for R-Car Gen4 instead of
+R-Car Gen3:
+ - EtherAVB,
+ - MSIOF.
+
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/387168aef20d399d4f4318f4ecab9c3b016fd6f2.1666605756.git.geert+renesas@glider.be
+Stable-dep-of: 0c51912331f8 ("arm64: dts: renesas: r8a779a0: Correct avb[01] reg sizes")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/renesas/r8a779a0.dtsi | 24 +++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
+index ed9400f903c9e..41fbb9998cf82 100644
+--- a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
+@@ -656,7 +656,7 @@ channel7 {
+
+ avb0: ethernet@e6800000 {
+ compatible = "renesas,etheravb-r8a779a0",
+- "renesas,etheravb-rcar-gen3";
++ "renesas,etheravb-rcar-gen4";
+ reg = <0 0xe6800000 0 0x800>;
+ interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>,
+@@ -704,7 +704,7 @@ avb0: ethernet@e6800000 {
+
+ avb1: ethernet@e6810000 {
+ compatible = "renesas,etheravb-r8a779a0",
+- "renesas,etheravb-rcar-gen3";
++ "renesas,etheravb-rcar-gen4";
+ reg = <0 0xe6810000 0 0x800>;
+ interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
+@@ -752,7 +752,7 @@ avb1: ethernet@e6810000 {
+
+ avb2: ethernet@e6820000 {
+ compatible = "renesas,etheravb-r8a779a0",
+- "renesas,etheravb-rcar-gen3";
++ "renesas,etheravb-rcar-gen4";
+ reg = <0 0xe6820000 0 0x1000>;
+ interrupts = <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
+@@ -800,7 +800,7 @@ avb2: ethernet@e6820000 {
+
+ avb3: ethernet@e6830000 {
+ compatible = "renesas,etheravb-r8a779a0",
+- "renesas,etheravb-rcar-gen3";
++ "renesas,etheravb-rcar-gen4";
+ reg = <0 0xe6830000 0 0x1000>;
+ interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>,
+@@ -848,7 +848,7 @@ avb3: ethernet@e6830000 {
+
+ avb4: ethernet@e6840000 {
+ compatible = "renesas,etheravb-r8a779a0",
+- "renesas,etheravb-rcar-gen3";
++ "renesas,etheravb-rcar-gen4";
+ reg = <0 0xe6840000 0 0x1000>;
+ interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>,
+@@ -896,7 +896,7 @@ avb4: ethernet@e6840000 {
+
+ avb5: ethernet@e6850000 {
+ compatible = "renesas,etheravb-r8a779a0",
+- "renesas,etheravb-rcar-gen3";
++ "renesas,etheravb-rcar-gen4";
+ reg = <0 0xe6850000 0 0x1000>;
+ interrupts = <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH>,
+@@ -1019,7 +1019,7 @@ tpu: pwm@e6e80000 {
+
+ msiof0: spi@e6e90000 {
+ compatible = "renesas,msiof-r8a779a0",
+- "renesas,rcar-gen3-msiof";
++ "renesas,rcar-gen4-msiof";
+ reg = <0 0xe6e90000 0 0x0064>;
+ interrupts = <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 618>;
+@@ -1034,7 +1034,7 @@ msiof0: spi@e6e90000 {
+
+ msiof1: spi@e6ea0000 {
+ compatible = "renesas,msiof-r8a779a0",
+- "renesas,rcar-gen3-msiof";
++ "renesas,rcar-gen4-msiof";
+ reg = <0 0xe6ea0000 0 0x0064>;
+ interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 619>;
+@@ -1049,7 +1049,7 @@ msiof1: spi@e6ea0000 {
+
+ msiof2: spi@e6c00000 {
+ compatible = "renesas,msiof-r8a779a0",
+- "renesas,rcar-gen3-msiof";
++ "renesas,rcar-gen4-msiof";
+ reg = <0 0xe6c00000 0 0x0064>;
+ interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 620>;
+@@ -1064,7 +1064,7 @@ msiof2: spi@e6c00000 {
+
+ msiof3: spi@e6c10000 {
+ compatible = "renesas,msiof-r8a779a0",
+- "renesas,rcar-gen3-msiof";
++ "renesas,rcar-gen4-msiof";
+ reg = <0 0xe6c10000 0 0x0064>;
+ interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 621>;
+@@ -1079,7 +1079,7 @@ msiof3: spi@e6c10000 {
+
+ msiof4: spi@e6c20000 {
+ compatible = "renesas,msiof-r8a779a0",
+- "renesas,rcar-gen3-msiof";
++ "renesas,rcar-gen4-msiof";
+ reg = <0 0xe6c20000 0 0x0064>;
+ interrupts = <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 622>;
+@@ -1094,7 +1094,7 @@ msiof4: spi@e6c20000 {
+
+ msiof5: spi@e6c28000 {
+ compatible = "renesas,msiof-r8a779a0",
+- "renesas,rcar-gen3-msiof";
++ "renesas,rcar-gen4-msiof";
+ reg = <0 0xe6c28000 0 0x0064>;
+ interrupts = <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 623>;
+--
+2.43.0
+
--- /dev/null
+From cbb8c07a6ef05b04a34fbb370255b92a1f1af8cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Feb 2024 15:21:31 +0100
+Subject: arm64: dts: renesas: r8a779g0: Correct avb[01] reg sizes
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 7edbb5880dc3317a5eaec2166de71ff394598e6b ]
+
+All Ethernet AVB instances on R-Car V4H have registers related to UDP/IP
+support, but the declared register blocks for the first two instances
+are too small to cover them.
+
+Fix this by extending the register block sizes.
+
+Fixes: 848c82db56923a8b ("arm64: dts: renesas: r8a779g0: Add RAVB nodes")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/83437778614a7c96f4d8f1be98dffeee29bb4a0b.1707660323.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/renesas/r8a779g0.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
+index d58b18802cb01..868d1a3cbdf61 100644
+--- a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
+@@ -337,7 +337,7 @@ hscif0: serial@e6540000 {
+ avb0: ethernet@e6800000 {
+ compatible = "renesas,etheravb-r8a779g0",
+ "renesas,etheravb-rcar-gen4";
+- reg = <0 0xe6800000 0 0x800>;
++ reg = <0 0xe6800000 0 0x1000>;
+ interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>,
+@@ -384,7 +384,7 @@ avb0: ethernet@e6800000 {
+ avb1: ethernet@e6810000 {
+ compatible = "renesas,etheravb-r8a779g0",
+ "renesas,etheravb-rcar-gen4";
+- reg = <0 0xe6810000 0 0x800>;
++ reg = <0 0xe6810000 0 0x1000>;
+ interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 362 IRQ_TYPE_LEVEL_HIGH>,
+--
+2.43.0
+
--- /dev/null
+From 5141537520236c5c4b24ca2ecaca2ea1282276d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Oct 2022 23:06:29 +0100
+Subject: arm64: dts: renesas: r9a07g043: Split out RZ/G2UL SoC specific parts
+
+From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+
+[ Upstream commit b9a0be2054964026aa58966ce9724b672f210835 ]
+
+Move RZ/G2UL SoC specific parts to r9a07g043u.dtsi so that
+r9a07g043.dtsi can be shared with RZ/Five (RISC-V SoC).
+
+Below are the changes due to which SoC specific parts are moved to
+r9a07g043u.dtsi:
+ - RZ/G2UL has Cortex-A55 (ARM64) whereas RZ/Five has AX45MP (RISC-V),
+ - RZ/G2UL has GICv3 as interrupt controller whereas RZ/Five has PLIC,
+ - RZ/G2UL has interrupts for SYSC block whereas interrupts are missing
+ for SYSC block on RZ/Five,
+ - RZ/G2UL has armv8-timer whereas RZ/Five has riscv-timer,
+ - RZ/G2UL has PSCI whereas RZ/Five have OpenSBI.
+
+Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Link: https://lore.kernel.org/r/20221025220629.79321-3-prabhakar.mahadev-lad.rj@bp.renesas.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Stable-dep-of: 14fe225dd5fc ("arm64: dts: renesas: rzg2l: Add missing interrupts to IRQC nodes")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/renesas/r9a07g043.dtsi | 54 +------------------
+ arch/arm64/boot/dts/renesas/r9a07g043u.dtsi | 60 +++++++++++++++++++++
+ 2 files changed, 61 insertions(+), 53 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r9a07g043.dtsi b/arch/arm64/boot/dts/renesas/r9a07g043.dtsi
+index a4738842f0646..7f88395ff7997 100644
+--- a/arch/arm64/boot/dts/renesas/r9a07g043.dtsi
++++ b/arch/arm64/boot/dts/renesas/r9a07g043.dtsi
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+ /*
+- * Device Tree Source for the RZ/G2UL SoC
++ * Device Tree Source for the RZ/Five and RZ/G2UL SoCs
+ *
+ * Copyright (C) 2022 Renesas Electronics Corp.
+ */
+@@ -68,36 +68,8 @@ opp-1000000000 {
+ };
+ };
+
+- cpus {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- cpu0: cpu@0 {
+- compatible = "arm,cortex-a55";
+- reg = <0>;
+- device_type = "cpu";
+- #cooling-cells = <2>;
+- next-level-cache = <&L3_CA55>;
+- enable-method = "psci";
+- clocks = <&cpg CPG_CORE R9A07G043_CLK_I>;
+- operating-points-v2 = <&cluster0_opp>;
+- };
+-
+- L3_CA55: cache-controller-0 {
+- compatible = "cache";
+- cache-unified;
+- cache-size = <0x40000>;
+- };
+- };
+-
+- psci {
+- compatible = "arm,psci-1.0", "arm,psci-0.2";
+- method = "smc";
+- };
+-
+ soc: soc {
+ compatible = "simple-bus";
+- interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+@@ -545,12 +517,6 @@ cpg: clock-controller@11010000 {
+ sysc: system-controller@11020000 {
+ compatible = "renesas,r9a07g043-sysc";
+ reg = <0 0x11020000 0 0x10000>;
+- interrupts = <SOC_PERIPHERAL_IRQ(42) IRQ_TYPE_LEVEL_HIGH>,
+- <SOC_PERIPHERAL_IRQ(43) IRQ_TYPE_LEVEL_HIGH>,
+- <SOC_PERIPHERAL_IRQ(44) IRQ_TYPE_LEVEL_HIGH>,
+- <SOC_PERIPHERAL_IRQ(45) IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "lpm_int", "ca55stbydone_int",
+- "cm33stbyr_int", "ca55_deny";
+ status = "disabled";
+ };
+
+@@ -603,16 +569,6 @@ dmac: dma-controller@11820000 {
+ dma-channels = <16>;
+ };
+
+- gic: interrupt-controller@11900000 {
+- compatible = "arm,gic-v3";
+- #interrupt-cells = <3>;
+- #address-cells = <0>;
+- interrupt-controller;
+- reg = <0x0 0x11900000 0 0x40000>,
+- <0x0 0x11940000 0 0x60000>;
+- interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
+- };
+-
+ sdhi0: mmc@11c00000 {
+ compatible = "renesas,sdhi-r9a07g043",
+ "renesas,rcar-gen3-sdhi";
+@@ -893,12 +849,4 @@ target: trip-point {
+ };
+ };
+ };
+-
+- timer {
+- compatible = "arm,armv8-timer";
+- interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+- <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+- <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+- <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
+- };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi b/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi
+index 96f935bc2d4d1..b8bf06b512351 100644
+--- a/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi
++++ b/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi
+@@ -10,3 +10,63 @@
+ #define SOC_PERIPHERAL_IRQ(nr) GIC_SPI nr
+
+ #include "r9a07g043.dtsi"
++
++/ {
++ cpus {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ cpu0: cpu@0 {
++ compatible = "arm,cortex-a55";
++ reg = <0>;
++ device_type = "cpu";
++ #cooling-cells = <2>;
++ next-level-cache = <&L3_CA55>;
++ enable-method = "psci";
++ clocks = <&cpg CPG_CORE R9A07G043_CLK_I>;
++ operating-points-v2 = <&cluster0_opp>;
++ };
++
++ L3_CA55: cache-controller-0 {
++ compatible = "cache";
++ cache-unified;
++ cache-size = <0x40000>;
++ };
++ };
++
++ psci {
++ compatible = "arm,psci-1.0", "arm,psci-0.2";
++ method = "smc";
++ };
++
++ timer {
++ compatible = "arm,armv8-timer";
++ interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
++ <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
++ <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
++ <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
++ };
++};
++
++&soc {
++ interrupt-parent = <&gic>;
++
++ gic: interrupt-controller@11900000 {
++ compatible = "arm,gic-v3";
++ #interrupt-cells = <3>;
++ #address-cells = <0>;
++ interrupt-controller;
++ reg = <0x0 0x11900000 0 0x40000>,
++ <0x0 0x11940000 0 0x60000>;
++ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
++ };
++};
++
++&sysc {
++ interrupts = <SOC_PERIPHERAL_IRQ(42) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(43) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(44) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(45) IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "lpm_int", "ca55stbydone_int",
++ "cm33stbyr_int", "ca55_deny";
++};
+--
+2.43.0
+
--- /dev/null
+From e546b682f0584433f0491796d38a00cbb7fa130f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Jan 2023 22:18:13 +0000
+Subject: arm64: dts: renesas: r9a07g043u: Add IRQC node
+
+From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+
+[ Upstream commit 48ab6eddd8bbcf7e9c8ae27bf42d0b52a777aaba ]
+
+Add IRQC node to R9A07G043 (RZ/G2UL) SoC DTSI.
+
+Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/20230102221815.273719-5-prabhakar.mahadev-lad.rj@bp.renesas.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Stable-dep-of: 14fe225dd5fc ("arm64: dts: renesas: rzg2l: Add missing interrupts to IRQC nodes")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/renesas/r9a07g043u.dtsi | 68 +++++++++++++++++++++
+ 1 file changed, 68 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi b/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi
+index b8bf06b512351..a6e777aee02ee 100644
+--- a/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi
++++ b/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi
+@@ -51,6 +51,74 @@ timer {
+ &soc {
+ interrupt-parent = <&gic>;
+
++ irqc: interrupt-controller@110a0000 {
++ compatible = "renesas,r9a07g043u-irqc",
++ "renesas,rzg2l-irqc";
++ reg = <0 0x110a0000 0 0x10000>;
++ #interrupt-cells = <2>;
++ #address-cells = <0>;
++ interrupt-controller;
++ interrupts = <SOC_PERIPHERAL_IRQ(0) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(1) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(2) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(3) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(4) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(5) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(6) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(7) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(8) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(444) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(445) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(446) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(447) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(448) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(449) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(450) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(451) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(452) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(453) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(454) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(455) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(456) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(457) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(458) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(459) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(460) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(461) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(462) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(463) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(464) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(465) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(466) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(467) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(468) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(469) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(470) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(471) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(472) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(473) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(474) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(475) IRQ_TYPE_LEVEL_HIGH>,
++ <SOC_PERIPHERAL_IRQ(25) IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "nmi",
++ "irq0", "irq1", "irq2", "irq3",
++ "irq4", "irq5", "irq6", "irq7",
++ "tint0", "tint1", "tint2", "tint3",
++ "tint4", "tint5", "tint6", "tint7",
++ "tint8", "tint9", "tint10", "tint11",
++ "tint12", "tint13", "tint14", "tint15",
++ "tint16", "tint17", "tint18", "tint19",
++ "tint20", "tint21", "tint22", "tint23",
++ "tint24", "tint25", "tint26", "tint27",
++ "tint28", "tint29", "tint30", "tint31",
++ "bus-err";
++ clocks = <&cpg CPG_MOD R9A07G043_IA55_CLK>,
++ <&cpg CPG_MOD R9A07G043_IA55_PCLK>;
++ clock-names = "clk", "pclk";
++ power-domains = <&cpg>;
++ resets = <&cpg R9A07G043_IA55_RESETN>;
++ };
++
+ gic: interrupt-controller@11900000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+--
+2.43.0
+
--- /dev/null
+From 66fc433c489e2db5fc1621166aaf9cb6ce9165c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Feb 2024 14:44:20 +0000
+Subject: arm64: dts: renesas: rzg2l: Add missing interrupts to IRQC nodes
+
+From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+
+[ Upstream commit 14fe225dd5fcd5928583b0bcc34398a581f51602 ]
+
+The IRQC IP block supports Bus error and ECCRAM interrupts on RZ/G2L and
+alike SoC's (listed below). Update the IRQC nodes with the missing
+interrupts, and additionally, include the 'interrupt-names' properties
+in the IRQC nodes so that the driver can parse interrupts by name.
+
+ - R9A07G043U - RZ/G2UL
+ - R9A07G044L/R9A07G044LC - RZ/{G2L,G2LC}
+ - R9A07G054 - RZ/V2L
+
+Fixes: 5edc51af5b30 ("arm64: dts: renesas: r9a07g044: Add IRQC node")
+Fixes: 48ab6eddd8bb ("arm64: dts: renesas: r9a07g043u: Add IRQC node")
+Fixes: 379478ab09e0 ("arm64: dts: renesas: r9a07g054: Add IRQC node")
+Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/20240205144421.51195-3-prabhakar.mahadev-lad.rj@bp.renesas.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/renesas/r9a07g043u.dtsi | 12 +++++++++--
+ arch/arm64/boot/dts/renesas/r9a07g044.dtsi | 22 ++++++++++++++++++++-
+ arch/arm64/boot/dts/renesas/r9a07g054.dtsi | 22 ++++++++++++++++++++-
+ 3 files changed, 52 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi b/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi
+index a6e777aee02ee..011d4c88f4ed9 100644
+--- a/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi
++++ b/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi
+@@ -99,7 +99,13 @@ irqc: interrupt-controller@110a0000 {
+ <SOC_PERIPHERAL_IRQ(473) IRQ_TYPE_LEVEL_HIGH>,
+ <SOC_PERIPHERAL_IRQ(474) IRQ_TYPE_LEVEL_HIGH>,
+ <SOC_PERIPHERAL_IRQ(475) IRQ_TYPE_LEVEL_HIGH>,
+- <SOC_PERIPHERAL_IRQ(25) IRQ_TYPE_EDGE_RISING>;
++ <SOC_PERIPHERAL_IRQ(25) IRQ_TYPE_EDGE_RISING>,
++ <SOC_PERIPHERAL_IRQ(34) IRQ_TYPE_EDGE_RISING>,
++ <SOC_PERIPHERAL_IRQ(35) IRQ_TYPE_EDGE_RISING>,
++ <SOC_PERIPHERAL_IRQ(36) IRQ_TYPE_EDGE_RISING>,
++ <SOC_PERIPHERAL_IRQ(37) IRQ_TYPE_EDGE_RISING>,
++ <SOC_PERIPHERAL_IRQ(38) IRQ_TYPE_EDGE_RISING>,
++ <SOC_PERIPHERAL_IRQ(39) IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "nmi",
+ "irq0", "irq1", "irq2", "irq3",
+ "irq4", "irq5", "irq6", "irq7",
+@@ -111,7 +117,9 @@ irqc: interrupt-controller@110a0000 {
+ "tint20", "tint21", "tint22", "tint23",
+ "tint24", "tint25", "tint26", "tint27",
+ "tint28", "tint29", "tint30", "tint31",
+- "bus-err";
++ "bus-err", "ec7tie1-0", "ec7tie2-0",
++ "ec7tiovf-0", "ec7tie1-1", "ec7tie2-1",
++ "ec7tiovf-1";
+ clocks = <&cpg CPG_MOD R9A07G043_IA55_CLK>,
+ <&cpg CPG_MOD R9A07G043_IA55_PCLK>;
+ clock-names = "clk", "pclk";
+diff --git a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
+index 7dbf6a6292f49..d26488b5a82df 100644
+--- a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
++++ b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
+@@ -698,7 +698,27 @@ irqc: interrupt-controller@110a0000 {
+ <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>;
++ <GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 35 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 36 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 37 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 38 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 39 IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "nmi", "irq0", "irq1", "irq2", "irq3",
++ "irq4", "irq5", "irq6", "irq7",
++ "tint0", "tint1", "tint2", "tint3",
++ "tint4", "tint5", "tint6", "tint7",
++ "tint8", "tint9", "tint10", "tint11",
++ "tint12", "tint13", "tint14", "tint15",
++ "tint16", "tint17", "tint18", "tint19",
++ "tint20", "tint21", "tint22", "tint23",
++ "tint24", "tint25", "tint26", "tint27",
++ "tint28", "tint29", "tint30", "tint31",
++ "bus-err", "ec7tie1-0", "ec7tie2-0",
++ "ec7tiovf-0", "ec7tie1-1", "ec7tie2-1",
++ "ec7tiovf-1";
+ clocks = <&cpg CPG_MOD R9A07G044_IA55_CLK>,
+ <&cpg CPG_MOD R9A07G044_IA55_PCLK>;
+ clock-names = "clk", "pclk";
+diff --git a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
+index e000510b90a42..b3d37ca942ee3 100644
+--- a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
++++ b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
+@@ -704,7 +704,27 @@ irqc: interrupt-controller@110a0000 {
+ <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>;
++ <GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 35 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 36 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 37 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 38 IRQ_TYPE_EDGE_RISING>,
++ <GIC_SPI 39 IRQ_TYPE_EDGE_RISING>;
++ interrupt-names = "nmi", "irq0", "irq1", "irq2", "irq3",
++ "irq4", "irq5", "irq6", "irq7",
++ "tint0", "tint1", "tint2", "tint3",
++ "tint4", "tint5", "tint6", "tint7",
++ "tint8", "tint9", "tint10", "tint11",
++ "tint12", "tint13", "tint14", "tint15",
++ "tint16", "tint17", "tint18", "tint19",
++ "tint20", "tint21", "tint22", "tint23",
++ "tint24", "tint25", "tint26", "tint27",
++ "tint28", "tint29", "tint30", "tint31",
++ "bus-err", "ec7tie1-0", "ec7tie2-0",
++ "ec7tiovf-0", "ec7tie1-1", "ec7tie2-1",
++ "ec7tiovf-1";
+ clocks = <&cpg CPG_MOD R9A07G054_IA55_CLK>,
+ <&cpg CPG_MOD R9A07G054_IA55_PCLK>;
+ clock-names = "clk", "pclk";
+--
+2.43.0
+
--- /dev/null
+From 3ce6f6c042f78a04e57c8beb08a99cb788879d4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Feb 2024 18:35:25 +0100
+Subject: arm64: dts: rockchip: add missing interrupt-names for rk356x vdpu
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Heiko Stuebner <heiko@sntech.de>
+
+[ Upstream commit d1c44d9afa6f89aa0e10a191f30868eb12cd719f ]
+
+The video-codec@fdea0400 was missing the interrupt-names property that is
+part of the binding. Add it.
+
+Fixes: 944be6fba401 ("arm64: dts: rockchip: Add VPU support for RK3568/RK3566")
+Cc: Piotr Oniszczuk <piotr.oniszczuk@gmail.com>
+Acked-by: Uwe Kleine-König <ukleinek@debian.org>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://lore.kernel.org/r/20240227173526.710056-1-heiko@sntech.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk356x.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+index f4d6dbbbddcd4..99ad6fc51b584 100644
+--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+@@ -596,6 +596,7 @@ vpu: video-codec@fdea0400 {
+ compatible = "rockchip,rk3568-vpu";
+ reg = <0x0 0xfdea0000 0x0 0x800>;
+ interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "vdpu";
+ clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+ clock-names = "aclk", "hclk";
+ iommus = <&vdpu_mmu>;
+--
+2.43.0
+
--- /dev/null
+From de7021857dc135e98476a97c94aa804bd8473c50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Dec 2023 05:07:21 +0200
+Subject: ASoC: amd: acp: Add missing error handling in sof-mach
+
+From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+
+[ Upstream commit d0ada20279db2649a7549a2b8a4a3379c59f238d ]
+
+Handle potential acp_sofdsp_dai_links_create() errors in ACP SOF machine
+driver's probe function. Note there is no need for an undo.
+
+While at it, switch to dev_err_probe().
+
+Fixes: 9f84940f5004 ("ASoC: amd: acp: Add SOF audio support on Chrome board")
+Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
+Link: https://msgid.link/r/20231219030728.2431640-4-cristian.ciocaltea@collabora.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/amd/acp/acp-sof-mach.c | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/sound/soc/amd/acp/acp-sof-mach.c b/sound/soc/amd/acp/acp-sof-mach.c
+index f19f064a75272..972600d271586 100644
+--- a/sound/soc/amd/acp/acp-sof-mach.c
++++ b/sound/soc/amd/acp/acp-sof-mach.c
+@@ -114,16 +114,14 @@ static int acp_sof_probe(struct platform_device *pdev)
+ card->num_controls = ARRAY_SIZE(acp_controls);
+ card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data;
+
+- acp_sofdsp_dai_links_create(card);
++ ret = acp_sofdsp_dai_links_create(card);
++ if (ret)
++ return dev_err_probe(&pdev->dev, ret, "Failed to create DAI links\n");
+
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
+- if (ret) {
+- dev_err(&pdev->dev,
+- "devm_snd_soc_register_card(%s) failed: %d\n",
+- card->name, ret);
+- return ret;
+- }
+-
++ if (ret)
++ return dev_err_probe(&pdev->dev, ret,
++ "Failed to register card(%s)\n", card->name);
+ return 0;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 7d2ed8f4147bd9d7fea846e3262918beb31819ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Feb 2024 22:58:03 +0100
+Subject: ASoC: meson: aiu: fix function pointer type mismatch
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+[ Upstream commit 98ac85a00f31d2e9d5452b825a9ed0153d934043 ]
+
+clang-16 warns about casting functions to incompatible types, as is done
+here to call clk_disable_unprepare:
+
+sound/soc/meson/aiu.c:243:12: error: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+ 243 | (void(*)(void *))clk_disable_unprepare,
+
+The pattern of getting, enabling and setting a disable callback for a
+clock can be replaced with devm_clk_get_enabled(), which also fixes
+this warning.
+
+Fixes: 6ae9ca9ce986 ("ASoC: meson: aiu: add i2s and spdif support")
+Reported-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Reviewed-by: Justin Stitt <justinstitt@google.com>
+Link: https://msgid.link/r/20240213215807.3326688-2-jbrunet@baylibre.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/meson/aiu.c | 19 ++++---------------
+ sound/soc/meson/aiu.h | 1 -
+ 2 files changed, 4 insertions(+), 16 deletions(-)
+
+diff --git a/sound/soc/meson/aiu.c b/sound/soc/meson/aiu.c
+index 88e611e64d14f..077b9c0b6c4ca 100644
+--- a/sound/soc/meson/aiu.c
++++ b/sound/soc/meson/aiu.c
+@@ -218,11 +218,12 @@ static const char * const aiu_spdif_ids[] = {
+ static int aiu_clk_get(struct device *dev)
+ {
+ struct aiu *aiu = dev_get_drvdata(dev);
++ struct clk *pclk;
+ int ret;
+
+- aiu->pclk = devm_clk_get(dev, "pclk");
+- if (IS_ERR(aiu->pclk))
+- return dev_err_probe(dev, PTR_ERR(aiu->pclk), "Can't get the aiu pclk\n");
++ pclk = devm_clk_get_enabled(dev, "pclk");
++ if (IS_ERR(pclk))
++ return dev_err_probe(dev, PTR_ERR(pclk), "Can't get the aiu pclk\n");
+
+ aiu->spdif_mclk = devm_clk_get(dev, "spdif_mclk");
+ if (IS_ERR(aiu->spdif_mclk))
+@@ -239,18 +240,6 @@ static int aiu_clk_get(struct device *dev)
+ if (ret)
+ return dev_err_probe(dev, ret, "Can't get the spdif clocks\n");
+
+- ret = clk_prepare_enable(aiu->pclk);
+- if (ret) {
+- dev_err(dev, "peripheral clock enable failed\n");
+- return ret;
+- }
+-
+- ret = devm_add_action_or_reset(dev,
+- (void(*)(void *))clk_disable_unprepare,
+- aiu->pclk);
+- if (ret)
+- dev_err(dev, "failed to add reset action on pclk");
+-
+ return ret;
+ }
+
+diff --git a/sound/soc/meson/aiu.h b/sound/soc/meson/aiu.h
+index 393b6c2307e49..0f94c8bf60818 100644
+--- a/sound/soc/meson/aiu.h
++++ b/sound/soc/meson/aiu.h
+@@ -33,7 +33,6 @@ struct aiu_platform_data {
+ };
+
+ struct aiu {
+- struct clk *pclk;
+ struct clk *spdif_mclk;
+ struct aiu_interface i2s;
+ struct aiu_interface spdif;
+--
+2.43.0
+
--- /dev/null
+From 0c368e6e9ada2cdfcfa7ce46626201d7367b7e70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Feb 2024 18:51:08 +0100
+Subject: ASoC: meson: axg-tdm-interface: add frame rate constraint
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+[ Upstream commit 59c6a3a43b221cc2a211181b1298e43b2c2df782 ]
+
+According to Amlogic datasheets for the SoCs supported by this driver, the
+maximum bit clock rate is 100MHz.
+
+The tdm interface allows the rates listed by the DAI driver, regardless of
+the number slots or their width. However, these will impact the bit clock
+rate.
+
+Hitting the 100MHz limit is very unlikely for most use cases but it is
+possible.
+
+For example with 32 slots / 32 bits wide, the maximum rate is no longer
+384kHz but ~96kHz.
+
+Add the constraint accordingly if the component is not already active.
+If it is active, the rate is already constrained by the first stream rate.
+
+Fixes: d60e4f1e4be5 ("ASoC: meson: add tdm interface driver")
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Link: https://msgid.link/r/20240223175116.2005407-3-jbrunet@baylibre.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/meson/axg-tdm-interface.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/sound/soc/meson/axg-tdm-interface.c b/sound/soc/meson/axg-tdm-interface.c
+index eb188ee950557..028383f949efd 100644
+--- a/sound/soc/meson/axg-tdm-interface.c
++++ b/sound/soc/meson/axg-tdm-interface.c
+@@ -12,6 +12,9 @@
+
+ #include "axg-tdm.h"
+
++/* Maximum bit clock frequency according the datasheets */
++#define MAX_SCLK 100000000 /* Hz */
++
+ enum {
+ TDM_IFACE_PAD,
+ TDM_IFACE_LOOPBACK,
+@@ -155,19 +158,27 @@ static int axg_tdm_iface_startup(struct snd_pcm_substream *substream,
+ return -EINVAL;
+ }
+
+- /* Apply component wide rate symmetry */
+ if (snd_soc_component_active(dai->component)) {
++ /* Apply component wide rate symmetry */
+ ret = snd_pcm_hw_constraint_single(substream->runtime,
+ SNDRV_PCM_HW_PARAM_RATE,
+ iface->rate);
+- if (ret < 0) {
+- dev_err(dai->dev,
+- "can't set iface rate constraint\n");
+- return ret;
+- }
++
++ } else {
++ /* Limit rate according to the slot number and width */
++ unsigned int max_rate =
++ MAX_SCLK / (iface->slots * iface->slot_width);
++ ret = snd_pcm_hw_constraint_minmax(substream->runtime,
++ SNDRV_PCM_HW_PARAM_RATE,
++ 0, max_rate);
+ }
+
+- return 0;
++ if (ret < 0)
++ dev_err(dai->dev, "can't set iface rate constraint\n");
++ else
++ ret = 0;
++
++ return ret;
+ }
+
+ static int axg_tdm_iface_set_stream(struct snd_pcm_substream *substream,
+--
+2.43.0
+
--- /dev/null
+From a146a3086b5ea0eff184a327f49d316019cb85f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Feb 2024 18:51:07 +0100
+Subject: ASoC: meson: axg-tdm-interface: fix mclk setup without mclk-fs
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+[ Upstream commit e3741a8d28a1137f8b19ae6f3d6e3be69a454a0a ]
+
+By default, when mclk-fs is not provided, the tdm-interface driver
+requests an MCLK that is 4x the bit clock, SCLK.
+
+However there is no justification for this:
+
+* If the codec needs MCLK for its operation, mclk-fs is expected to be set
+ according to the codec requirements.
+* If the codec does not need MCLK the minimum is 2 * SCLK, because this is
+ minimum the divider between SCLK and MCLK can do.
+
+Multiplying by 4 may cause problems because the PLL limit may be reached
+sooner than it should, so use 2x instead.
+
+Fixes: d60e4f1e4be5 ("ASoC: meson: add tdm interface driver")
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Link: https://msgid.link/r/20240223175116.2005407-2-jbrunet@baylibre.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/meson/axg-tdm-interface.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/meson/axg-tdm-interface.c b/sound/soc/meson/axg-tdm-interface.c
+index c040c83637e02..eb188ee950557 100644
+--- a/sound/soc/meson/axg-tdm-interface.c
++++ b/sound/soc/meson/axg-tdm-interface.c
+@@ -266,8 +266,8 @@ static int axg_tdm_iface_set_sclk(struct snd_soc_dai *dai,
+ srate = iface->slots * iface->slot_width * params_rate(params);
+
+ if (!iface->mclk_rate) {
+- /* If no specific mclk is requested, default to bit clock * 4 */
+- clk_set_rate(iface->mclk, 4 * srate);
++ /* If no specific mclk is requested, default to bit clock * 2 */
++ clk_set_rate(iface->mclk, 2 * srate);
+ } else {
+ /* Check if we can actually get the bit clock from mclk */
+ if (iface->mclk_rate % srate) {
+--
+2.43.0
+
--- /dev/null
+From 7ae4b5ba5c0396e14d39537b446bdbca49ef6f61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Feb 2024 22:58:04 +0100
+Subject: ASoC: meson: t9015: fix function pointer type mismatch
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+[ Upstream commit 5ad992c71b6a8e8a547954addc7af9fbde6ca10a ]
+
+clang-16 warns about casting functions to incompatible types, as is done
+here to call clk_disable_unprepare:
+
+sound/soc/meson/t9015.c:274:4: error: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+ 274 | (void(*)(void *))clk_disable_unprepare,
+
+The pattern of getting, enabling and setting a disable callback for a
+clock can be replaced with devm_clk_get_enabled(), which also fixes
+this warning.
+
+Fixes: 33901f5b9b16 ("ASoC: meson: add t9015 internal DAC driver")
+Reported-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Reviewed-by: Justin Stitt <justinstitt@google.com>
+Link: https://msgid.link/r/20240213215807.3326688-3-jbrunet@baylibre.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/meson/t9015.c | 20 ++++----------------
+ 1 file changed, 4 insertions(+), 16 deletions(-)
+
+diff --git a/sound/soc/meson/t9015.c b/sound/soc/meson/t9015.c
+index 9c6b4dac68932..571f65788c592 100644
+--- a/sound/soc/meson/t9015.c
++++ b/sound/soc/meson/t9015.c
+@@ -48,7 +48,6 @@
+ #define POWER_CFG 0x10
+
+ struct t9015 {
+- struct clk *pclk;
+ struct regulator *avdd;
+ };
+
+@@ -249,6 +248,7 @@ static int t9015_probe(struct platform_device *pdev)
+ struct t9015 *priv;
+ void __iomem *regs;
+ struct regmap *regmap;
++ struct clk *pclk;
+ int ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+@@ -256,26 +256,14 @@ static int t9015_probe(struct platform_device *pdev)
+ return -ENOMEM;
+ platform_set_drvdata(pdev, priv);
+
+- priv->pclk = devm_clk_get(dev, "pclk");
+- if (IS_ERR(priv->pclk))
+- return dev_err_probe(dev, PTR_ERR(priv->pclk), "failed to get core clock\n");
++ pclk = devm_clk_get_enabled(dev, "pclk");
++ if (IS_ERR(pclk))
++ return dev_err_probe(dev, PTR_ERR(pclk), "failed to get core clock\n");
+
+ priv->avdd = devm_regulator_get(dev, "AVDD");
+ if (IS_ERR(priv->avdd))
+ return dev_err_probe(dev, PTR_ERR(priv->avdd), "failed to AVDD\n");
+
+- ret = clk_prepare_enable(priv->pclk);
+- if (ret) {
+- dev_err(dev, "core clock enable failed\n");
+- return ret;
+- }
+-
+- ret = devm_add_action_or_reset(dev,
+- (void(*)(void *))clk_disable_unprepare,
+- priv->pclk);
+- if (ret)
+- return ret;
+-
+ ret = device_reset(dev);
+ if (ret) {
+ dev_err(dev, "reset failed\n");
+--
+2.43.0
+
--- /dev/null
+From 4ea57b12696f017b2a02623d5b1800eb95d6cce4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Feb 2024 16:02:16 +0300
+Subject: ASoC: SOF: Add some bounds checking to firmware data
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 98f681b0f84cfc3a1d83287b77697679e0398306 ]
+
+Smatch complains about "head->full_size - head->header_size" can
+underflow. To some extent, we're always going to have to trust the
+firmware a bit. However, it's easy enough to add a check for negatives,
+and let's add a upper bounds check as well.
+
+Fixes: d2458baa799f ("ASoC: SOF: ipc3-loader: Implement firmware parsing and loading")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://msgid.link/r/5593d147-058c-4de3-a6f5-540ecb96f6f8@moroto.mountain
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/ipc3-loader.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/sound/soc/sof/ipc3-loader.c b/sound/soc/sof/ipc3-loader.c
+index 28218766d2114..6e3ef06721106 100644
+--- a/sound/soc/sof/ipc3-loader.c
++++ b/sound/soc/sof/ipc3-loader.c
+@@ -148,6 +148,8 @@ static size_t sof_ipc3_fw_parse_ext_man(struct snd_sof_dev *sdev)
+
+ head = (struct sof_ext_man_header *)fw->data;
+ remaining = head->full_size - head->header_size;
++ if (remaining < 0 || remaining > sdev->basefw.fw->size)
++ return -EINVAL;
+ ext_man_size = ipc3_fw_ext_man_size(sdev, fw);
+
+ /* Assert firmware starts with extended manifest */
+--
+2.43.0
+
--- /dev/null
+From 3e83a7832d3b8e6b3c22b5ce529b04ddbddf3590 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Oct 2022 15:12:21 +0300
+Subject: ASoC: SOF: Introduce container struct for SOF firmware
+
+From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+
+[ Upstream commit 4f373ccf226e37a20fdc15a3df8034517a6045fd ]
+
+Move the firmware related information under a new struct (sof_firmware)
+and add it to the high level snd_sof_dev struct.
+
+Convert the generic code to use this new container when working with the
+basefw and for compatibility reasons set the old plat_data members used by
+the platforms.
+
+Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Chao Song <chao.song@intel.com>
+Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+Link: https://lore.kernel.org/r/20221020121238.18339-3-peter.ujfalusi@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 98f681b0f84c ("ASoC: SOF: Add some bounds checking to firmware data")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/ipc3-loader.c | 26 ++++++++++++--------------
+ sound/soc/sof/ipc4-loader.c | 6 ++----
+ sound/soc/sof/loader.c | 18 +++++++++++++-----
+ sound/soc/sof/sof-priv.h | 14 ++++++++++++++
+ 4 files changed, 41 insertions(+), 23 deletions(-)
+
+diff --git a/sound/soc/sof/ipc3-loader.c b/sound/soc/sof/ipc3-loader.c
+index bf423ca4e97bb..28218766d2114 100644
+--- a/sound/soc/sof/ipc3-loader.c
++++ b/sound/soc/sof/ipc3-loader.c
+@@ -138,8 +138,7 @@ static ssize_t ipc3_fw_ext_man_size(struct snd_sof_dev *sdev, const struct firmw
+
+ static size_t sof_ipc3_fw_parse_ext_man(struct snd_sof_dev *sdev)
+ {
+- struct snd_sof_pdata *plat_data = sdev->pdata;
+- const struct firmware *fw = plat_data->fw;
++ const struct firmware *fw = sdev->basefw.fw;
+ const struct sof_ext_man_elem_header *elem_hdr;
+ const struct sof_ext_man_header *head;
+ ssize_t ext_man_size;
+@@ -310,18 +309,18 @@ static int sof_ipc3_parse_module_memcpy(struct snd_sof_dev *sdev,
+
+ static int sof_ipc3_load_fw_to_dsp(struct snd_sof_dev *sdev)
+ {
+- struct snd_sof_pdata *plat_data = sdev->pdata;
+- const struct firmware *fw = plat_data->fw;
++ u32 payload_offset = sdev->basefw.payload_offset;
++ const struct firmware *fw = sdev->basefw.fw;
+ struct snd_sof_fw_header *header;
+ struct snd_sof_mod_hdr *module;
+ int (*load_module)(struct snd_sof_dev *sof_dev, struct snd_sof_mod_hdr *hdr);
+ size_t remaining;
+ int ret, count;
+
+- if (!plat_data->fw)
++ if (!fw)
+ return -EINVAL;
+
+- header = (struct snd_sof_fw_header *)(fw->data + plat_data->fw_offset);
++ header = (struct snd_sof_fw_header *)(fw->data + payload_offset);
+ load_module = sof_ops(sdev)->load_module;
+ if (!load_module) {
+ dev_dbg(sdev->dev, "Using generic module loading\n");
+@@ -331,9 +330,8 @@ static int sof_ipc3_load_fw_to_dsp(struct snd_sof_dev *sdev)
+ }
+
+ /* parse each module */
+- module = (struct snd_sof_mod_hdr *)(fw->data + plat_data->fw_offset +
+- sizeof(*header));
+- remaining = fw->size - sizeof(*header) - plat_data->fw_offset;
++ module = (struct snd_sof_mod_hdr *)(fw->data + payload_offset + sizeof(*header));
++ remaining = fw->size - sizeof(*header) - payload_offset;
+ /* check for wrap */
+ if (remaining > fw->size) {
+ dev_err(sdev->dev, "%s: fw size smaller than header size\n", __func__);
+@@ -374,19 +372,19 @@ static int sof_ipc3_load_fw_to_dsp(struct snd_sof_dev *sdev)
+
+ static int sof_ipc3_validate_firmware(struct snd_sof_dev *sdev)
+ {
+- struct snd_sof_pdata *plat_data = sdev->pdata;
+- const struct firmware *fw = plat_data->fw;
++ u32 payload_offset = sdev->basefw.payload_offset;
++ const struct firmware *fw = sdev->basefw.fw;
+ struct snd_sof_fw_header *header;
+- size_t fw_size = fw->size - plat_data->fw_offset;
++ size_t fw_size = fw->size - payload_offset;
+
+- if (fw->size <= plat_data->fw_offset) {
++ if (fw->size <= payload_offset) {
+ dev_err(sdev->dev,
+ "firmware size must be greater than firmware offset\n");
+ return -EINVAL;
+ }
+
+ /* Read the header information from the data pointer */
+- header = (struct snd_sof_fw_header *)(fw->data + plat_data->fw_offset);
++ header = (struct snd_sof_fw_header *)(fw->data + payload_offset);
+
+ /* verify FW sig */
+ if (strncmp(header->sig, SND_SOF_FW_SIG, SND_SOF_FW_SIG_SIZE) != 0) {
+diff --git a/sound/soc/sof/ipc4-loader.c b/sound/soc/sof/ipc4-loader.c
+index e635ae515fa9f..9f433e9b4cd37 100644
+--- a/sound/soc/sof/ipc4-loader.c
++++ b/sound/soc/sof/ipc4-loader.c
+@@ -17,9 +17,8 @@
+ static size_t sof_ipc4_fw_parse_ext_man(struct snd_sof_dev *sdev)
+ {
+ struct sof_ipc4_fw_data *ipc4_data = sdev->private;
+- struct snd_sof_pdata *plat_data = sdev->pdata;
+ struct sof_man4_fw_binary_header *fw_header;
+- const struct firmware *fw = plat_data->fw;
++ const struct firmware *fw = sdev->basefw.fw;
+ struct sof_ext_manifest4_hdr *ext_man_hdr;
+ struct sof_man4_module_config *fm_config;
+ struct sof_ipc4_fw_module *fw_module;
+@@ -138,9 +137,8 @@ static int sof_ipc4_validate_firmware(struct snd_sof_dev *sdev)
+ {
+ struct sof_ipc4_fw_data *ipc4_data = sdev->private;
+ u32 fw_hdr_offset = ipc4_data->manifest_fw_hdr_offset;
+- struct snd_sof_pdata *plat_data = sdev->pdata;
+ struct sof_man4_fw_binary_header *fw_header;
+- const struct firmware *fw = plat_data->fw;
++ const struct firmware *fw = sdev->basefw.fw;
+ struct sof_ext_manifest4_hdr *ext_man_hdr;
+
+ ext_man_hdr = (struct sof_ext_manifest4_hdr *)fw->data;
+diff --git a/sound/soc/sof/loader.c b/sound/soc/sof/loader.c
+index 5f51d936b3067..ba8e3aae0a5cb 100644
+--- a/sound/soc/sof/loader.c
++++ b/sound/soc/sof/loader.c
+@@ -22,7 +22,7 @@ int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev)
+ int ret;
+
+ /* Don't request firmware again if firmware is already requested */
+- if (plat_data->fw)
++ if (sdev->basefw.fw)
+ return 0;
+
+ fw_filename = kasprintf(GFP_KERNEL, "%s/%s",
+@@ -31,7 +31,7 @@ int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev)
+ if (!fw_filename)
+ return -ENOMEM;
+
+- ret = request_firmware(&plat_data->fw, fw_filename, sdev->dev);
++ ret = request_firmware(&sdev->basefw.fw, fw_filename, sdev->dev);
+
+ if (ret < 0) {
+ dev_err(sdev->dev,
+@@ -48,7 +48,7 @@ int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev)
+ ext_man_size = sdev->ipc->ops->fw_loader->parse_ext_manifest(sdev);
+ if (ext_man_size > 0) {
+ /* when no error occurred, drop extended manifest */
+- plat_data->fw_offset = ext_man_size;
++ sdev->basefw.payload_offset = ext_man_size;
+ } else if (!ext_man_size) {
+ /* No extended manifest, so nothing to skip during FW load */
+ dev_dbg(sdev->dev, "firmware doesn't contain extended manifest\n");
+@@ -58,6 +58,12 @@ int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev)
+ fw_filename, ret);
+ }
+
++ /*
++ * Until the platform code is switched to use the new container the fw
++ * and payload offset must be set in plat_data
++ */
++ plat_data->fw = sdev->basefw.fw;
++ plat_data->fw_offset = sdev->basefw.payload_offset;
+ err:
+ kfree(fw_filename);
+
+@@ -100,7 +106,8 @@ int snd_sof_load_firmware_memcpy(struct snd_sof_dev *sdev)
+ return 0;
+
+ error:
+- release_firmware(plat_data->fw);
++ release_firmware(sdev->basefw.fw);
++ sdev->basefw.fw = NULL;
+ plat_data->fw = NULL;
+ return ret;
+
+@@ -185,7 +192,8 @@ EXPORT_SYMBOL(snd_sof_run_firmware);
+ void snd_sof_fw_unload(struct snd_sof_dev *sdev)
+ {
+ /* TODO: support module unloading at runtime */
+- release_firmware(sdev->pdata->fw);
++ release_firmware(sdev->basefw.fw);
++ sdev->basefw.fw = NULL;
+ sdev->pdata->fw = NULL;
+ }
+ EXPORT_SYMBOL(snd_sof_fw_unload);
+diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
+index de08825915b35..3d70b57e4864d 100644
+--- a/sound/soc/sof/sof-priv.h
++++ b/sound/soc/sof/sof-priv.h
+@@ -136,6 +136,17 @@ struct snd_sof_platform_stream_params {
+ bool cont_update_posn;
+ };
+
++/**
++ * struct sof_firmware - Container struct for SOF firmware
++ * @fw: Pointer to the firmware
++ * @payload_offset: Offset of the data within the loaded firmware image to be
++ * loaded to the DSP (skipping for example ext_manifest section)
++ */
++struct sof_firmware {
++ const struct firmware *fw;
++ u32 payload_offset;
++};
++
+ /*
+ * SOF DSP HW abstraction operations.
+ * Used to abstract DSP HW architecture and any IO busses between host CPU
+@@ -487,6 +498,9 @@ struct snd_sof_dev {
+ spinlock_t ipc_lock; /* lock for IPC users */
+ spinlock_t hw_lock; /* lock for HW IO access */
+
++ /* Main, Base firmware image */
++ struct sof_firmware basefw;
++
+ /*
+ * ASoC components. plat_drv fields are set dynamically so
+ * can't use const
+--
+2.43.0
+
--- /dev/null
+From 78baa41b7868ba548be70b0cfc9f598bf8ed4f46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Feb 2024 15:35:24 +0000
+Subject: backlight: da9052: Fully initialize backlight_properties during probe
+
+From: Daniel Thompson <daniel.thompson@linaro.org>
+
+[ Upstream commit 0285e9efaee8276305db5c52a59baf84e9731556 ]
+
+props is stack allocated and the fields that are not explcitly set
+by the probe function need to be zeroed or we'll get undefined behaviour
+(especially so power/blank states)!
+
+Fixes: 6ede3d832aaa ("backlight: add driver for DA9052/53 PMIC v1")
+Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
+Link: https://lore.kernel.org/r/20240220153532.76613-2-daniel.thompson@linaro.org
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/backlight/da9052_bl.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/video/backlight/da9052_bl.c b/drivers/video/backlight/da9052_bl.c
+index 882359dd288c0..aa00379392a0f 100644
+--- a/drivers/video/backlight/da9052_bl.c
++++ b/drivers/video/backlight/da9052_bl.c
+@@ -117,6 +117,7 @@ static int da9052_backlight_probe(struct platform_device *pdev)
+ wleds->led_reg = platform_get_device_id(pdev)->driver_data;
+ wleds->state = DA9052_WLEDS_OFF;
+
++ memset(&props, 0, sizeof(struct backlight_properties));
+ props.type = BACKLIGHT_RAW;
+ props.max_brightness = DA9052_MAX_BRIGHTNESS;
+
+--
+2.43.0
+
--- /dev/null
+From 83d16a5f3a3bd49a569aae336568c5d8d6b9aba9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Feb 2024 00:11:20 +0100
+Subject: backlight: lm3630a: Don't set bl->props.brightness in get_brightness
+
+From: Luca Weiss <luca@z3ntu.xyz>
+
+[ Upstream commit 4bf7ddd2d2f0f8826f25f74c7eba4e2c323a1446 ]
+
+There's no need to set bl->props.brightness, the get_brightness function
+is just supposed to return the current brightness and not touch the
+struct.
+
+With that done we can also remove the 'goto out' and just return the
+value.
+
+Fixes: 0c2a665a648e ("backlight: add Backlight driver for lm3630 chip")
+Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
+Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
+Link: https://lore.kernel.org/r/20240220-lm3630a-fixups-v1-2-9ca62f7e4a33@z3ntu.xyz
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/backlight/lm3630a_bl.c | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c
+index 855c275754578..0d43f6326750f 100644
+--- a/drivers/video/backlight/lm3630a_bl.c
++++ b/drivers/video/backlight/lm3630a_bl.c
+@@ -231,7 +231,7 @@ static int lm3630a_bank_a_get_brightness(struct backlight_device *bl)
+ if (rval < 0)
+ goto out_i2c_err;
+ brightness |= rval;
+- goto out;
++ return brightness;
+ }
+
+ /* disable sleep */
+@@ -242,11 +242,8 @@ static int lm3630a_bank_a_get_brightness(struct backlight_device *bl)
+ rval = lm3630a_read(pchip, REG_BRT_A);
+ if (rval < 0)
+ goto out_i2c_err;
+- brightness = rval;
++ return rval;
+
+-out:
+- bl->props.brightness = brightness;
+- return bl->props.brightness;
+ out_i2c_err:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return 0;
+@@ -306,7 +303,7 @@ static int lm3630a_bank_b_get_brightness(struct backlight_device *bl)
+ if (rval < 0)
+ goto out_i2c_err;
+ brightness |= rval;
+- goto out;
++ return brightness;
+ }
+
+ /* disable sleep */
+@@ -317,11 +314,8 @@ static int lm3630a_bank_b_get_brightness(struct backlight_device *bl)
+ rval = lm3630a_read(pchip, REG_BRT_B);
+ if (rval < 0)
+ goto out_i2c_err;
+- brightness = rval;
++ return rval;
+
+-out:
+- bl->props.brightness = brightness;
+- return bl->props.brightness;
+ out_i2c_err:
+ dev_err(pchip->dev, "i2c failed to access register\n");
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From 4c5e07424f1f12b17057d589d8792eb49e7df289 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Feb 2024 00:11:19 +0100
+Subject: backlight: lm3630a: Initialize backlight_properties on init
+
+From: Luca Weiss <luca@z3ntu.xyz>
+
+[ Upstream commit ad9aeb0e3aa90ebdad5fabf9c21783740eb95907 ]
+
+The backlight_properties struct should be initialized to zero before
+using, otherwise there will be some random values in the struct.
+
+Fixes: 0c2a665a648e ("backlight: add Backlight driver for lm3630 chip")
+Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
+Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
+Link: https://lore.kernel.org/r/20240220-lm3630a-fixups-v1-1-9ca62f7e4a33@z3ntu.xyz
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/backlight/lm3630a_bl.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c
+index 475f35635bf67..855c275754578 100644
+--- a/drivers/video/backlight/lm3630a_bl.c
++++ b/drivers/video/backlight/lm3630a_bl.c
+@@ -339,6 +339,7 @@ static int lm3630a_backlight_register(struct lm3630a_chip *pchip)
+ struct backlight_properties props;
+ const char *label;
+
++ memset(&props, 0, sizeof(struct backlight_properties));
+ props.type = BACKLIGHT_RAW;
+ if (pdata->leda_ctrl != LM3630A_LEDA_DISABLE) {
+ props.brightness = pdata->leda_init_brt;
+--
+2.43.0
+
--- /dev/null
+From bd3c04feddcd490852bfe3b926db9b2943366598 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Feb 2024 15:35:25 +0000
+Subject: backlight: lm3639: Fully initialize backlight_properties during probe
+
+From: Daniel Thompson <daniel.thompson@linaro.org>
+
+[ Upstream commit abb5a5d951fbea3feb5c4ba179b89bb96a1d3462 ]
+
+props is stack allocated and the fields that are not explcitly set
+by the probe function need to be zeroed or we'll get undefined behaviour
+(especially so power/blank states)!
+
+Fixes: 0f59858d5119 ("backlight: add new lm3639 backlight driver")
+Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
+Link: https://lore.kernel.org/r/20240220153532.76613-3-daniel.thompson@linaro.org
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/backlight/lm3639_bl.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/video/backlight/lm3639_bl.c b/drivers/video/backlight/lm3639_bl.c
+index 6580911671a3e..4c9726a7fa720 100644
+--- a/drivers/video/backlight/lm3639_bl.c
++++ b/drivers/video/backlight/lm3639_bl.c
+@@ -339,6 +339,7 @@ static int lm3639_probe(struct i2c_client *client,
+ }
+
+ /* backlight */
++ memset(&props, 0, sizeof(struct backlight_properties));
+ props.type = BACKLIGHT_RAW;
+ props.brightness = pdata->init_brt_led;
+ props.max_brightness = pdata->max_brt_led;
+--
+2.43.0
+
--- /dev/null
+From cd47cbb72316bd1bd00bf9ce43c995a06db6fb14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Feb 2024 15:35:26 +0000
+Subject: backlight: lp8788: Fully initialize backlight_properties during probe
+
+From: Daniel Thompson <daniel.thompson@linaro.org>
+
+[ Upstream commit 392346827fbe8a7fd573dfb145170d7949f639a6 ]
+
+props is stack allocated and the fields that are not explcitly set
+by the probe function need to be zeroed or we'll get undefined behaviour
+(especially so power/blank states)!
+
+Fixes: c5a51053cf3b ("backlight: add new lp8788 backlight driver")
+Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
+Link: https://lore.kernel.org/r/20240220153532.76613-4-daniel.thompson@linaro.org
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/backlight/lp8788_bl.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/video/backlight/lp8788_bl.c b/drivers/video/backlight/lp8788_bl.c
+index ba42f3fe0c739..d9b95dbd40d30 100644
+--- a/drivers/video/backlight/lp8788_bl.c
++++ b/drivers/video/backlight/lp8788_bl.c
+@@ -191,6 +191,7 @@ static int lp8788_backlight_register(struct lp8788_bl *bl)
+ int init_brt;
+ char *name;
+
++ memset(&props, 0, sizeof(struct backlight_properties));
+ props.type = BACKLIGHT_PLATFORM;
+ props.max_brightness = MAX_BRIGHTNESS;
+
+--
+2.43.0
+
--- /dev/null
+From d3f2f0968e8c5733ecf823ad109278c4311a1ee5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Mar 2024 12:58:11 -0500
+Subject: Bluetooth: af_bluetooth: Fix deadlock
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit f7b94bdc1ec107c92262716b073b3e816d4784fb ]
+
+Attemting to do sock_lock on .recvmsg may cause a deadlock as shown
+bellow, so instead of using sock_sock this uses sk_receive_queue.lock
+on bt_sock_ioctl to avoid the UAF:
+
+INFO: task kworker/u9:1:121 blocked for more than 30 seconds.
+ Not tainted 6.7.6-lemon #183
+Workqueue: hci0 hci_rx_work
+Call Trace:
+ <TASK>
+ __schedule+0x37d/0xa00
+ schedule+0x32/0xe0
+ __lock_sock+0x68/0xa0
+ ? __pfx_autoremove_wake_function+0x10/0x10
+ lock_sock_nested+0x43/0x50
+ l2cap_sock_recv_cb+0x21/0xa0
+ l2cap_recv_frame+0x55b/0x30a0
+ ? psi_task_switch+0xeb/0x270
+ ? finish_task_switch.isra.0+0x93/0x2a0
+ hci_rx_work+0x33a/0x3f0
+ process_one_work+0x13a/0x2f0
+ worker_thread+0x2f0/0x410
+ ? __pfx_worker_thread+0x10/0x10
+ kthread+0xe0/0x110
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork+0x2c/0x50
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork_asm+0x1b/0x30
+ </TASK>
+
+Fixes: 2e07e8348ea4 ("Bluetooth: af_bluetooth: Fix Use-After-Free in bt_sock_recvmsg")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/af_bluetooth.c | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
+index f1b7510359e4b..3f9ff02baafe3 100644
+--- a/net/bluetooth/af_bluetooth.c
++++ b/net/bluetooth/af_bluetooth.c
+@@ -264,14 +264,11 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
+ if (flags & MSG_OOB)
+ return -EOPNOTSUPP;
+
+- lock_sock(sk);
+-
+ skb = skb_recv_datagram(sk, flags, &err);
+ if (!skb) {
+ if (sk->sk_shutdown & RCV_SHUTDOWN)
+ err = 0;
+
+- release_sock(sk);
+ return err;
+ }
+
+@@ -297,8 +294,6 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
+
+ skb_free_datagram(sk, skb);
+
+- release_sock(sk);
+-
+ if (flags & MSG_TRUNC)
+ copied = skblen;
+
+@@ -521,10 +516,11 @@ int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+ if (sk->sk_state == BT_LISTEN)
+ return -EINVAL;
+
+- lock_sock(sk);
++ spin_lock(&sk->sk_receive_queue.lock);
+ skb = skb_peek(&sk->sk_receive_queue);
+ amount = skb ? skb->len : 0;
+- release_sock(sk);
++ spin_unlock(&sk->sk_receive_queue.lock);
++
+ err = put_user(amount, (int __user *)arg);
+ break;
+
+--
+2.43.0
+
--- /dev/null
+From df15a8921d37be32232f39c719b007c3ef37296d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Apr 2023 20:23:36 +0800
+Subject: Bluetooth: Cancel sync command before suspend and power off
+
+From: Archie Pusaka <apusaka@chromium.org>
+
+[ Upstream commit f419863588217f76eaf754e1dfce21ea7fcb026d ]
+
+Some of the sync commands might take a long time to complete, e.g.
+LE Create Connection when the peer device isn't responding might take
+20 seconds before it times out. If suspend command is issued during
+this time, it will need to wait for completion since both commands are
+using the same sync lock.
+
+This patch cancel any running sync commands before attempting to
+suspend or adapter power off.
+
+Signed-off-by: Archie Pusaka <apusaka@chromium.org>
+Reviewed-by: Ying Hsu <yinghsu@chromium.org>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 2615fd9a7c25 ("Bluetooth: hci_sync: Fix overwriting request callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_core.c | 3 +++
+ net/bluetooth/mgmt.c | 4 ++++
+ 2 files changed, 7 insertions(+)
+
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index a8932d449eb63..a7e6ce2e61c5e 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -2838,6 +2838,9 @@ int hci_suspend_dev(struct hci_dev *hdev)
+ if (mgmt_powering_down(hdev))
+ return 0;
+
++ /* Cancel potentially blocking sync operation before suspend */
++ __hci_cmd_sync_cancel(hdev, -EHOSTDOWN);
++
+ hci_req_sync_lock(hdev);
+ ret = hci_suspend_sync(hdev);
+ hci_req_sync_unlock(hdev);
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index a80bf9c42c2ef..a657dc1d4ec7a 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -1401,6 +1401,10 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
+ goto failed;
+ }
+
++ /* Cancel potentially blocking sync operation before power off */
++ if (cp->val == 0x00)
++ __hci_cmd_sync_cancel(hdev, -EHOSTDOWN);
++
+ err = hci_cmd_sync_queue(hdev, set_powered_sync, cmd,
+ mgmt_set_powered_complete);
+
+--
+2.43.0
+
--- /dev/null
+From a29e24655dbae87dc6786cc2525a55bcefde482b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 17:42:05 +0100
+Subject: Bluetooth: Fix eir name length
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Frédéric Danis <frederic.danis@collabora.com>
+
+[ Upstream commit 2ab3e8d67fc1d4a7638b769cf83023ec209fc0a9 ]
+
+According to Section 1.2 of Core Specification Supplement Part A the
+complete or short name strings are defined as utf8s, which should not
+include the trailing NULL for variable length array as defined in Core
+Specification Vol1 Part E Section 2.9.3.
+
+Removing the trailing NULL allows PTS to retrieve the random address based
+on device name, e.g. for SM/PER/KDU/BV-02-C, SM/PER/KDU/BV-08-C or
+GAP/BROB/BCST/BV-03-C.
+
+Fixes: f61851f64b17 ("Bluetooth: Fix append max 11 bytes of name to scan rsp data")
+Signed-off-by: Frédéric Danis <frederic.danis@collabora.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/eir.c | 29 +++++++----------------------
+ net/bluetooth/mgmt.c | 2 +-
+ 2 files changed, 8 insertions(+), 23 deletions(-)
+
+diff --git a/net/bluetooth/eir.c b/net/bluetooth/eir.c
+index 9214189279e80..1bc51e2b05a34 100644
+--- a/net/bluetooth/eir.c
++++ b/net/bluetooth/eir.c
+@@ -13,48 +13,33 @@
+
+ #define PNP_INFO_SVCLASS_ID 0x1200
+
+-static u8 eir_append_name(u8 *eir, u16 eir_len, u8 type, u8 *data, u8 data_len)
+-{
+- u8 name[HCI_MAX_SHORT_NAME_LENGTH + 1];
+-
+- /* If data is already NULL terminated just pass it directly */
+- if (data[data_len - 1] == '\0')
+- return eir_append_data(eir, eir_len, type, data, data_len);
+-
+- memcpy(name, data, HCI_MAX_SHORT_NAME_LENGTH);
+- name[HCI_MAX_SHORT_NAME_LENGTH] = '\0';
+-
+- return eir_append_data(eir, eir_len, type, name, sizeof(name));
+-}
+-
+ u8 eir_append_local_name(struct hci_dev *hdev, u8 *ptr, u8 ad_len)
+ {
+ size_t short_len;
+ size_t complete_len;
+
+- /* no space left for name (+ NULL + type + len) */
+- if ((max_adv_len(hdev) - ad_len) < HCI_MAX_SHORT_NAME_LENGTH + 3)
++ /* no space left for name (+ type + len) */
++ if ((max_adv_len(hdev) - ad_len) < HCI_MAX_SHORT_NAME_LENGTH + 2)
+ return ad_len;
+
+ /* use complete name if present and fits */
+ complete_len = strnlen(hdev->dev_name, sizeof(hdev->dev_name));
+ if (complete_len && complete_len <= HCI_MAX_SHORT_NAME_LENGTH)
+- return eir_append_name(ptr, ad_len, EIR_NAME_COMPLETE,
+- hdev->dev_name, complete_len + 1);
++ return eir_append_data(ptr, ad_len, EIR_NAME_COMPLETE,
++ hdev->dev_name, complete_len);
+
+ /* use short name if present */
+ short_len = strnlen(hdev->short_name, sizeof(hdev->short_name));
+ if (short_len)
+- return eir_append_name(ptr, ad_len, EIR_NAME_SHORT,
++ return eir_append_data(ptr, ad_len, EIR_NAME_SHORT,
+ hdev->short_name,
+- short_len == HCI_MAX_SHORT_NAME_LENGTH ?
+- short_len : short_len + 1);
++ short_len);
+
+ /* use shortened full name if present, we already know that name
+ * is longer then HCI_MAX_SHORT_NAME_LENGTH
+ */
+ if (complete_len)
+- return eir_append_name(ptr, ad_len, EIR_NAME_SHORT,
++ return eir_append_data(ptr, ad_len, EIR_NAME_SHORT,
+ hdev->dev_name,
+ HCI_MAX_SHORT_NAME_LENGTH);
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 21c0924787e22..716f6dc4934b7 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -8465,7 +8465,7 @@ static int read_adv_features(struct sock *sk, struct hci_dev *hdev,
+
+ static u8 calculate_name_len(struct hci_dev *hdev)
+ {
+- u8 buf[HCI_MAX_SHORT_NAME_LENGTH + 3];
++ u8 buf[HCI_MAX_SHORT_NAME_LENGTH + 2]; /* len + type + name */
+
+ return eir_append_local_name(hdev, buf, 0);
+ }
+--
+2.43.0
+
--- /dev/null
+From 6d97dbde11f38d6e12844d1a02b47b8146b73004 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Mar 2024 19:06:23 +0200
+Subject: Bluetooth: fix use-after-free in accessing skb after sending it
+
+From: Pauli Virtanen <pav@iki.fi>
+
+[ Upstream commit 947ec0d002dce8577b655793dcc6fc78d67b7cb6 ]
+
+hci_send_cmd_sync first sends skb and then tries to clone it. However,
+the driver may have already freed the skb at that point.
+
+Fix by cloning the sent_cmd cloned just above, instead of the original.
+
+Log:
+================================================================
+BUG: KASAN: slab-use-after-free in __copy_skb_header+0x1a/0x240
+...
+Call Trace: ..
+ __skb_clone+0x59/0x2c0
+ hci_cmd_work+0x3b3/0x3d0 [bluetooth]
+ process_one_work+0x459/0x900
+...
+Allocated by task 129: ...
+ __alloc_skb+0x1ae/0x220
+ __hci_cmd_sync_sk+0x44c/0x7a0 [bluetooth]
+ __hci_cmd_sync_status+0x24/0xb0 [bluetooth]
+ set_cig_params_sync+0x778/0x7d0 [bluetooth]
+...
+Freed by task 0: ...
+ kmem_cache_free+0x157/0x3c0
+ __usb_hcd_giveback_urb+0x11e/0x1e0
+ usb_giveback_urb_bh+0x1ad/0x2a0
+ tasklet_action_common.isra.0+0x259/0x4a0
+ __do_softirq+0x15b/0x5a7
+================================================================
+
+Fixes: 2615fd9a7c25 ("Bluetooth: hci_sync: Fix overwriting request callback")
+Signed-off-by: Pauli Virtanen <pav@iki.fi>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 88e9d7e0865a2..70f24dc75b596 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -4176,7 +4176,7 @@ static void hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
+ if (hci_req_status_pend(hdev) &&
+ !hci_dev_test_and_set_flag(hdev, HCI_CMD_PENDING)) {
+ kfree_skb(hdev->req_skb);
+- hdev->req_skb = skb_clone(skb, GFP_KERNEL);
++ hdev->req_skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
+ }
+
+ atomic_dec(&hdev->cmd_cnt);
+--
+2.43.0
+
--- /dev/null
+From 213416bb06eec204c49ee9e535716e2f3310dce6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jun 2023 17:25:06 -0700
+Subject: Bluetooth: hci_conn: Consolidate code for aborting connections
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit a13f316e90fdb1fb6df6582e845aa9b3270f3581 ]
+
+This consolidates code for aborting connections using
+hci_cmd_sync_queue so it is synchronized with other threads, but
+because of the fact that some commands may block the cmd_sync_queue
+while waiting specific events this attempt to cancel those requests by
+using hci_cmd_sync_cancel.
+
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 2615fd9a7c25 ("Bluetooth: hci_sync: Fix overwriting request callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_core.h | 2 +-
+ net/bluetooth/hci_conn.c | 154 ++++++-------------------------
+ net/bluetooth/hci_sync.c | 23 +++--
+ net/bluetooth/mgmt.c | 15 +--
+ 4 files changed, 47 insertions(+), 147 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index 09c978f3d95dc..2538f3b96623b 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -739,6 +739,7 @@ struct hci_conn {
+ unsigned long flags;
+
+ enum conn_reasons conn_reason;
++ __u8 abort_reason;
+
+ __u32 clock;
+ __u16 clock_accuracy;
+@@ -758,7 +759,6 @@ struct hci_conn {
+ struct delayed_work auto_accept_work;
+ struct delayed_work idle_work;
+ struct delayed_work le_conn_timeout;
+- struct work_struct le_scan_cleanup;
+
+ struct device dev;
+ struct dentry *debugfs;
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 12d36875358b9..f752a9f9bb9c7 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -175,57 +175,6 @@ static void hci_conn_cleanup(struct hci_conn *conn)
+ hci_dev_put(hdev);
+ }
+
+-static void le_scan_cleanup(struct work_struct *work)
+-{
+- struct hci_conn *conn = container_of(work, struct hci_conn,
+- le_scan_cleanup);
+- struct hci_dev *hdev = conn->hdev;
+- struct hci_conn *c = NULL;
+-
+- BT_DBG("%s hcon %p", hdev->name, conn);
+-
+- hci_dev_lock(hdev);
+-
+- /* Check that the hci_conn is still around */
+- rcu_read_lock();
+- list_for_each_entry_rcu(c, &hdev->conn_hash.list, list) {
+- if (c == conn)
+- break;
+- }
+- rcu_read_unlock();
+-
+- if (c == conn) {
+- hci_connect_le_scan_cleanup(conn, 0x00);
+- hci_conn_cleanup(conn);
+- }
+-
+- hci_dev_unlock(hdev);
+- hci_dev_put(hdev);
+- hci_conn_put(conn);
+-}
+-
+-static void hci_connect_le_scan_remove(struct hci_conn *conn)
+-{
+- BT_DBG("%s hcon %p", conn->hdev->name, conn);
+-
+- /* We can't call hci_conn_del/hci_conn_cleanup here since that
+- * could deadlock with another hci_conn_del() call that's holding
+- * hci_dev_lock and doing cancel_delayed_work_sync(&conn->disc_work).
+- * Instead, grab temporary extra references to the hci_dev and
+- * hci_conn and perform the necessary cleanup in a separate work
+- * callback.
+- */
+-
+- hci_dev_hold(conn->hdev);
+- hci_conn_get(conn);
+-
+- /* Even though we hold a reference to the hdev, many other
+- * things might get cleaned up meanwhile, including the hdev's
+- * own workqueue, so we can't use that for scheduling.
+- */
+- schedule_work(&conn->le_scan_cleanup);
+-}
+-
+ static void hci_acl_create_connection(struct hci_conn *conn)
+ {
+ struct hci_dev *hdev = conn->hdev;
+@@ -672,13 +621,6 @@ static void hci_conn_timeout(struct work_struct *work)
+ if (refcnt > 0)
+ return;
+
+- /* LE connections in scanning state need special handling */
+- if (conn->state == BT_CONNECT && conn->type == LE_LINK &&
+- test_bit(HCI_CONN_SCANNING, &conn->flags)) {
+- hci_connect_le_scan_remove(conn);
+- return;
+- }
+-
+ hci_abort_conn(conn, hci_proto_disconn_ind(conn));
+ }
+
+@@ -1050,7 +992,6 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
+ INIT_DELAYED_WORK(&conn->auto_accept_work, hci_conn_auto_accept);
+ INIT_DELAYED_WORK(&conn->idle_work, hci_conn_idle);
+ INIT_DELAYED_WORK(&conn->le_conn_timeout, le_conn_timeout);
+- INIT_WORK(&conn->le_scan_cleanup, le_scan_cleanup);
+
+ atomic_set(&conn->refcnt, 0);
+
+@@ -2837,81 +2778,46 @@ u32 hci_conn_get_phy(struct hci_conn *conn)
+ return phys;
+ }
+
+-int hci_abort_conn(struct hci_conn *conn, u8 reason)
++static int abort_conn_sync(struct hci_dev *hdev, void *data)
+ {
+- int r = 0;
++ struct hci_conn *conn;
++ u16 handle = PTR_ERR(data);
+
+- if (test_and_set_bit(HCI_CONN_CANCEL, &conn->flags))
++ conn = hci_conn_hash_lookup_handle(hdev, handle);
++ if (!conn)
+ return 0;
+
+- switch (conn->state) {
+- case BT_CONNECTED:
+- case BT_CONFIG:
+- if (conn->type == AMP_LINK) {
+- struct hci_cp_disconn_phy_link cp;
++ return hci_abort_conn_sync(hdev, conn, conn->abort_reason);
++}
+
+- cp.phy_handle = HCI_PHY_HANDLE(conn->handle);
+- cp.reason = reason;
+- r = hci_send_cmd(conn->hdev, HCI_OP_DISCONN_PHY_LINK,
+- sizeof(cp), &cp);
+- } else {
+- struct hci_cp_disconnect dc;
++int hci_abort_conn(struct hci_conn *conn, u8 reason)
++{
++ struct hci_dev *hdev = conn->hdev;
+
+- dc.handle = cpu_to_le16(conn->handle);
+- dc.reason = reason;
+- r = hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT,
+- sizeof(dc), &dc);
+- }
++ /* If abort_reason has already been set it means the connection is
++ * already being aborted so don't attempt to overwrite it.
++ */
++ if (conn->abort_reason)
++ return 0;
+
+- conn->state = BT_DISCONN;
++ bt_dev_dbg(hdev, "handle 0x%2.2x reason 0x%2.2x", conn->handle, reason);
+
+- break;
+- case BT_CONNECT:
+- if (conn->type == LE_LINK) {
+- if (test_bit(HCI_CONN_SCANNING, &conn->flags))
+- break;
+- r = hci_send_cmd(conn->hdev,
+- HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL);
+- } else if (conn->type == ACL_LINK) {
+- if (conn->hdev->hci_ver < BLUETOOTH_VER_1_2)
+- break;
+- r = hci_send_cmd(conn->hdev,
+- HCI_OP_CREATE_CONN_CANCEL,
+- 6, &conn->dst);
+- }
+- break;
+- case BT_CONNECT2:
+- if (conn->type == ACL_LINK) {
+- struct hci_cp_reject_conn_req rej;
+-
+- bacpy(&rej.bdaddr, &conn->dst);
+- rej.reason = reason;
+-
+- r = hci_send_cmd(conn->hdev,
+- HCI_OP_REJECT_CONN_REQ,
+- sizeof(rej), &rej);
+- } else if (conn->type == SCO_LINK || conn->type == ESCO_LINK) {
+- struct hci_cp_reject_sync_conn_req rej;
+-
+- bacpy(&rej.bdaddr, &conn->dst);
+-
+- /* SCO rejection has its own limited set of
+- * allowed error values (0x0D-0x0F) which isn't
+- * compatible with most values passed to this
+- * function. To be safe hard-code one of the
+- * values that's suitable for SCO.
+- */
+- rej.reason = HCI_ERROR_REJ_LIMITED_RESOURCES;
++ conn->abort_reason = reason;
+
+- r = hci_send_cmd(conn->hdev,
+- HCI_OP_REJECT_SYNC_CONN_REQ,
+- sizeof(rej), &rej);
++ /* If the connection is pending check the command opcode since that
++ * might be blocking on hci_cmd_sync_work while waiting its respective
++ * event so we need to hci_cmd_sync_cancel to cancel it.
++ */
++ if (conn->state == BT_CONNECT && hdev->req_status == HCI_REQ_PEND) {
++ switch (hci_skb_event(hdev->sent_cmd)) {
++ case HCI_EV_LE_CONN_COMPLETE:
++ case HCI_EV_LE_ENHANCED_CONN_COMPLETE:
++ case HCI_EVT_LE_CIS_ESTABLISHED:
++ hci_cmd_sync_cancel(hdev, -ECANCELED);
++ break;
+ }
+- break;
+- default:
+- conn->state = BT_CLOSED;
+- break;
+ }
+
+- return r;
++ return hci_cmd_sync_queue(hdev, abort_conn_sync, ERR_PTR(conn->handle),
++ NULL);
+ }
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 31dd064d77a42..c03729c10fdd6 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -5230,22 +5230,27 @@ static int hci_disconnect_sync(struct hci_dev *hdev, struct hci_conn *conn,
+ }
+
+ static int hci_le_connect_cancel_sync(struct hci_dev *hdev,
+- struct hci_conn *conn)
++ struct hci_conn *conn, u8 reason)
+ {
++ /* Return reason if scanning since the connection shall probably be
++ * cleanup directly.
++ */
+ if (test_bit(HCI_CONN_SCANNING, &conn->flags))
+- return 0;
++ return reason;
+
+- if (test_and_set_bit(HCI_CONN_CANCEL, &conn->flags))
++ if (conn->role == HCI_ROLE_SLAVE ||
++ test_and_set_bit(HCI_CONN_CANCEL, &conn->flags))
+ return 0;
+
+ return __hci_cmd_sync_status(hdev, HCI_OP_LE_CREATE_CONN_CANCEL,
+ 0, NULL, HCI_CMD_TIMEOUT);
+ }
+
+-static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn)
++static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn,
++ u8 reason)
+ {
+ if (conn->type == LE_LINK)
+- return hci_le_connect_cancel_sync(hdev, conn);
++ return hci_le_connect_cancel_sync(hdev, conn, reason);
+
+ if (hdev->hci_ver < BLUETOOTH_VER_1_2)
+ return 0;
+@@ -5298,9 +5303,11 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason)
+ case BT_CONFIG:
+ return hci_disconnect_sync(hdev, conn, reason);
+ case BT_CONNECT:
+- err = hci_connect_cancel_sync(hdev, conn);
++ err = hci_connect_cancel_sync(hdev, conn, reason);
+ /* Cleanup hci_conn object if it cannot be cancelled as it
+- * likelly means the controller and host stack are out of sync.
++ * likelly means the controller and host stack are out of sync
++ * or in case of LE it was still scanning so it can be cleanup
++ * safely.
+ */
+ if (err) {
+ hci_dev_lock(hdev);
+@@ -6215,7 +6222,7 @@ int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn)
+
+ done:
+ if (err == -ETIMEDOUT)
+- hci_le_connect_cancel_sync(hdev, conn);
++ hci_le_connect_cancel_sync(hdev, conn, 0x00);
+
+ /* Re-enable advertising after the connection attempt is finished. */
+ hci_resume_advertising_sync(hdev);
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 732b6cf45fbe4..fbd859e2d13ca 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -3583,18 +3583,6 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
+ return err;
+ }
+
+-static int abort_conn_sync(struct hci_dev *hdev, void *data)
+-{
+- struct hci_conn *conn;
+- u16 handle = PTR_ERR(data);
+-
+- conn = hci_conn_hash_lookup_handle(hdev, handle);
+- if (!conn)
+- return 0;
+-
+- return hci_abort_conn_sync(hdev, conn, HCI_ERROR_REMOTE_USER_TERM);
+-}
+-
+ static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
+ u16 len)
+ {
+@@ -3645,8 +3633,7 @@ static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
+ le_addr_type(addr->type));
+
+ if (conn->conn_reason == CONN_REASON_PAIR_DEVICE)
+- hci_cmd_sync_queue(hdev, abort_conn_sync, ERR_PTR(conn->handle),
+- NULL);
++ hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
+
+ unlock:
+ hci_dev_unlock(hdev);
+--
+2.43.0
+
--- /dev/null
+From a11739c8f656d1f09608076a4075cfa8afcd5042 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jan 2024 13:45:40 -0500
+Subject: Bluetooth: hci_core: Cancel request on command timeout
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 63298d6e752fc0ec7f5093860af8bc9f047b30c8 ]
+
+If command has timed out call __hci_cmd_sync_cancel to notify the
+hci_req since it will inevitably cause a timeout.
+
+This also rework the code around __hci_cmd_sync_cancel since it was
+wrongly assuming it needs to cancel timer as well, but sometimes the
+timers have not been started or in fact they already had timed out in
+which case they don't need to be cancel yet again.
+
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 2615fd9a7c25 ("Bluetooth: hci_sync: Fix overwriting request callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_sync.h | 2 +-
+ net/bluetooth/hci_core.c | 86 +++++++++++++++++++++-----------
+ net/bluetooth/hci_request.c | 2 +-
+ net/bluetooth/hci_sync.c | 20 ++++----
+ net/bluetooth/mgmt.c | 2 +-
+ 5 files changed, 72 insertions(+), 40 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
+index 2fa976c466b80..59d15b1a978ab 100644
+--- a/include/net/bluetooth/hci_sync.h
++++ b/include/net/bluetooth/hci_sync.h
+@@ -39,7 +39,7 @@ int __hci_cmd_sync_status_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
+ void hci_cmd_sync_init(struct hci_dev *hdev);
+ void hci_cmd_sync_clear(struct hci_dev *hdev);
+ void hci_cmd_sync_cancel(struct hci_dev *hdev, int err);
+-void __hci_cmd_sync_cancel(struct hci_dev *hdev, int err);
++void hci_cmd_sync_cancel_sync(struct hci_dev *hdev, int err);
+
+ int hci_cmd_sync_submit(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
+ void *data, hci_cmd_sync_work_destroy_t destroy);
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index a7e6ce2e61c5e..edf7af2e13557 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -1492,10 +1492,11 @@ static void hci_cmd_timeout(struct work_struct *work)
+ cmd_timer.work);
+
+ if (hdev->sent_cmd) {
+- struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data;
+- u16 opcode = __le16_to_cpu(sent->opcode);
++ u16 opcode = hci_skb_opcode(hdev->sent_cmd);
+
+ bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode);
++
++ hci_cmd_sync_cancel_sync(hdev, ETIMEDOUT);
+ } else {
+ bt_dev_err(hdev, "command tx timeout");
+ }
+@@ -2822,6 +2823,23 @@ int hci_unregister_suspend_notifier(struct hci_dev *hdev)
+ return ret;
+ }
+
++/* Cancel ongoing command synchronously:
++ *
++ * - Cancel command timer
++ * - Reset command counter
++ * - Cancel command request
++ */
++static void hci_cancel_cmd_sync(struct hci_dev *hdev, int err)
++{
++ bt_dev_dbg(hdev, "err 0x%2.2x", err);
++
++ cancel_delayed_work_sync(&hdev->cmd_timer);
++ cancel_delayed_work_sync(&hdev->ncmd_timer);
++ atomic_set(&hdev->cmd_cnt, 1);
++
++ hci_cmd_sync_cancel_sync(hdev, -err);
++}
++
+ /* Suspend HCI device */
+ int hci_suspend_dev(struct hci_dev *hdev)
+ {
+@@ -2839,7 +2857,7 @@ int hci_suspend_dev(struct hci_dev *hdev)
+ return 0;
+
+ /* Cancel potentially blocking sync operation before suspend */
+- __hci_cmd_sync_cancel(hdev, -EHOSTDOWN);
++ hci_cancel_cmd_sync(hdev, -EHOSTDOWN);
+
+ hci_req_sync_lock(hdev);
+ ret = hci_suspend_sync(hdev);
+@@ -4119,6 +4137,33 @@ static void hci_rx_work(struct work_struct *work)
+ }
+ }
+
++static void hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
++{
++ int err;
++
++ bt_dev_dbg(hdev, "skb %p", skb);
++
++ kfree_skb(hdev->sent_cmd);
++
++ hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
++ if (!hdev->sent_cmd) {
++ skb_queue_head(&hdev->cmd_q, skb);
++ queue_work(hdev->workqueue, &hdev->cmd_work);
++ return;
++ }
++
++ err = hci_send_frame(hdev, skb);
++ if (err < 0) {
++ hci_cmd_sync_cancel_sync(hdev, err);
++ return;
++ }
++
++ if (hci_req_status_pend(hdev))
++ hci_dev_set_flag(hdev, HCI_CMD_PENDING);
++
++ atomic_dec(&hdev->cmd_cnt);
++}
++
+ static void hci_cmd_work(struct work_struct *work)
+ {
+ struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
+@@ -4133,30 +4178,15 @@ static void hci_cmd_work(struct work_struct *work)
+ if (!skb)
+ return;
+
+- kfree_skb(hdev->sent_cmd);
+-
+- hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
+- if (hdev->sent_cmd) {
+- int res;
+- if (hci_req_status_pend(hdev))
+- hci_dev_set_flag(hdev, HCI_CMD_PENDING);
+- atomic_dec(&hdev->cmd_cnt);
+-
+- res = hci_send_frame(hdev, skb);
+- if (res < 0)
+- __hci_cmd_sync_cancel(hdev, -res);
+-
+- rcu_read_lock();
+- if (test_bit(HCI_RESET, &hdev->flags) ||
+- hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
+- cancel_delayed_work(&hdev->cmd_timer);
+- else
+- queue_delayed_work(hdev->workqueue, &hdev->cmd_timer,
+- HCI_CMD_TIMEOUT);
+- rcu_read_unlock();
+- } else {
+- skb_queue_head(&hdev->cmd_q, skb);
+- queue_work(hdev->workqueue, &hdev->cmd_work);
+- }
++ hci_send_cmd_sync(hdev, skb);
++
++ rcu_read_lock();
++ if (test_bit(HCI_RESET, &hdev->flags) ||
++ hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
++ cancel_delayed_work(&hdev->cmd_timer);
++ else
++ queue_delayed_work(hdev->workqueue, &hdev->cmd_timer,
++ HCI_CMD_TIMEOUT);
++ rcu_read_unlock();
+ }
+ }
+diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
+index f7e006a363829..4468647df6722 100644
+--- a/net/bluetooth/hci_request.c
++++ b/net/bluetooth/hci_request.c
+@@ -916,7 +916,7 @@ void hci_request_setup(struct hci_dev *hdev)
+
+ void hci_request_cancel_all(struct hci_dev *hdev)
+ {
+- __hci_cmd_sync_cancel(hdev, ENODEV);
++ hci_cmd_sync_cancel_sync(hdev, ENODEV);
+
+ cancel_interleave_scan(hdev);
+ }
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index c03729c10fdd6..d0029f10d9023 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -651,7 +651,7 @@ void hci_cmd_sync_clear(struct hci_dev *hdev)
+ mutex_unlock(&hdev->cmd_sync_work_lock);
+ }
+
+-void __hci_cmd_sync_cancel(struct hci_dev *hdev, int err)
++void hci_cmd_sync_cancel(struct hci_dev *hdev, int err)
+ {
+ bt_dev_dbg(hdev, "err 0x%2.2x", err);
+
+@@ -659,15 +659,17 @@ void __hci_cmd_sync_cancel(struct hci_dev *hdev, int err)
+ hdev->req_result = err;
+ hdev->req_status = HCI_REQ_CANCELED;
+
+- cancel_delayed_work_sync(&hdev->cmd_timer);
+- cancel_delayed_work_sync(&hdev->ncmd_timer);
+- atomic_set(&hdev->cmd_cnt, 1);
+-
+- wake_up_interruptible(&hdev->req_wait_q);
++ queue_work(hdev->workqueue, &hdev->cmd_sync_cancel_work);
+ }
+ }
++EXPORT_SYMBOL(hci_cmd_sync_cancel);
+
+-void hci_cmd_sync_cancel(struct hci_dev *hdev, int err)
++/* Cancel ongoing command request synchronously:
++ *
++ * - Set result and mark status to HCI_REQ_CANCELED
++ * - Wakeup command sync thread
++ */
++void hci_cmd_sync_cancel_sync(struct hci_dev *hdev, int err)
+ {
+ bt_dev_dbg(hdev, "err 0x%2.2x", err);
+
+@@ -675,10 +677,10 @@ void hci_cmd_sync_cancel(struct hci_dev *hdev, int err)
+ hdev->req_result = err;
+ hdev->req_status = HCI_REQ_CANCELED;
+
+- queue_work(hdev->workqueue, &hdev->cmd_sync_cancel_work);
++ wake_up_interruptible(&hdev->req_wait_q);
+ }
+ }
+-EXPORT_SYMBOL(hci_cmd_sync_cancel);
++EXPORT_SYMBOL(hci_cmd_sync_cancel_sync);
+
+ /* Submit HCI command to be run in as cmd_sync_work:
+ *
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index fbd859e2d13ca..4a35535f56607 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -1403,7 +1403,7 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
+
+ /* Cancel potentially blocking sync operation before power off */
+ if (cp->val == 0x00) {
+- __hci_cmd_sync_cancel(hdev, -EHOSTDOWN);
++ hci_cmd_sync_cancel_sync(hdev, -EHOSTDOWN);
+ err = hci_cmd_sync_queue(hdev, set_powered_sync, cmd,
+ mgmt_set_powered_complete);
+ } else {
+--
+2.43.0
+
--- /dev/null
+From e0235ed31b46fe299808f2238d73a233ea79adde Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Aug 2023 14:19:27 -0700
+Subject: Bluetooth: hci_core: Fix missing instances using HCI_MAX_AD_LENGTH
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit db08722fc7d46168fe31d9b8a7b29229dd959f9f ]
+
+There a few instances still using HCI_MAX_AD_LENGTH instead of using
+max_adv_len which takes care of detecting what is the actual maximum
+length depending on if the controller supports EA or not.
+
+Fixes: 112b5090c219 ("Bluetooth: MGMT: Fix always using HCI_MAX_AD_LENGTH")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 2ab3e8d67fc1 ("Bluetooth: Fix eir name length")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_core.h | 6 +++---
+ net/bluetooth/eir.c | 2 +-
+ net/bluetooth/mgmt.c | 6 +++---
+ 3 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index 53155cb703b5d..c50a41f1782a4 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -81,7 +81,7 @@ struct discovery_state {
+ u8 last_adv_addr_type;
+ s8 last_adv_rssi;
+ u32 last_adv_flags;
+- u8 last_adv_data[HCI_MAX_AD_LENGTH];
++ u8 last_adv_data[HCI_MAX_EXT_AD_LENGTH];
+ u8 last_adv_data_len;
+ bool report_invalid_rssi;
+ bool result_filtering;
+@@ -293,7 +293,7 @@ struct adv_pattern {
+ __u8 ad_type;
+ __u8 offset;
+ __u8 length;
+- __u8 value[HCI_MAX_AD_LENGTH];
++ __u8 value[HCI_MAX_EXT_AD_LENGTH];
+ };
+
+ struct adv_rssi_thresholds {
+@@ -727,7 +727,7 @@ struct hci_conn {
+ __u16 le_conn_interval;
+ __u16 le_conn_latency;
+ __u16 le_supv_timeout;
+- __u8 le_adv_data[HCI_MAX_AD_LENGTH];
++ __u8 le_adv_data[HCI_MAX_EXT_AD_LENGTH];
+ __u8 le_adv_data_len;
+ __u8 le_per_adv_data[HCI_MAX_PER_AD_LENGTH];
+ __u8 le_per_adv_data_len;
+diff --git a/net/bluetooth/eir.c b/net/bluetooth/eir.c
+index 8a85f6cdfbc16..9214189279e80 100644
+--- a/net/bluetooth/eir.c
++++ b/net/bluetooth/eir.c
+@@ -33,7 +33,7 @@ u8 eir_append_local_name(struct hci_dev *hdev, u8 *ptr, u8 ad_len)
+ size_t complete_len;
+
+ /* no space left for name (+ NULL + type + len) */
+- if ((HCI_MAX_AD_LENGTH - ad_len) < HCI_MAX_SHORT_NAME_LENGTH + 3)
++ if ((max_adv_len(hdev) - ad_len) < HCI_MAX_SHORT_NAME_LENGTH + 3)
+ return ad_len;
+
+ /* use complete name if present and fits */
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 1486fb9bb78f7..21c0924787e22 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -5378,9 +5378,9 @@ static u8 parse_adv_monitor_pattern(struct adv_monitor *m, u8 pattern_count,
+ for (i = 0; i < pattern_count; i++) {
+ offset = patterns[i].offset;
+ length = patterns[i].length;
+- if (offset >= HCI_MAX_AD_LENGTH ||
+- length > HCI_MAX_AD_LENGTH ||
+- (offset + length) > HCI_MAX_AD_LENGTH)
++ if (offset >= HCI_MAX_EXT_AD_LENGTH ||
++ length > HCI_MAX_EXT_AD_LENGTH ||
++ (offset + length) > HCI_MAX_EXT_AD_LENGTH)
+ return MGMT_STATUS_INVALID_PARAMS;
+
+ p = kmalloc(sizeof(*p), GFP_KERNEL);
+--
+2.43.0
+
--- /dev/null
+From 33d40581fb1144dbcf9af55b6ad38bcf1c3f4494 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Feb 2024 10:49:26 -0500
+Subject: Bluetooth: hci_core: Fix possible buffer overflow
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 81137162bfaa7278785b24c1fd2e9e74f082e8e4 ]
+
+struct hci_dev_info has a fixed size name[8] field so in the event that
+hdev->name is bigger than that strcpy would attempt to write past its
+size, so this fixes this problem by switching to use strscpy.
+
+Fixes: dcda165706b9 ("Bluetooth: hci_core: Fix build warnings")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index e0c924df13b58..88e9d7e0865a2 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -908,7 +908,7 @@ int hci_get_dev_info(void __user *arg)
+ else
+ flags = hdev->flags;
+
+- strcpy(di.name, hdev->name);
++ strscpy(di.name, hdev->name, sizeof(di.name));
+ di.bdaddr = hdev->bdaddr;
+ di.type = (hdev->bus & 0x0f) | ((hdev->dev_type & 0x03) << 4);
+ di.flags = flags;
+--
+2.43.0
+
--- /dev/null
+From a6a051ebe30eb0db1dd1ad871487f2b34a094e85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Feb 2024 17:40:17 +0100
+Subject: Bluetooth: hci_qca: don't use IS_ERR_OR_NULL() with
+ gpiod_get_optional()
+
+From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+
+[ Upstream commit 56d074d26c5828773b00b2185dd7e1d08273b8e8 ]
+
+The optional variants for the gpiod_get() family of functions return NULL
+if the GPIO in question is not associated with this device. They return
+ERR_PTR() on any other error. NULL descriptors are graciously handled by
+GPIOLIB and can be safely passed to any of the GPIO consumer interfaces
+as they will return 0 and act as if the function succeeded. If one is
+using the optional variant, then there's no point in checking for NULL.
+
+Fixes: 6845667146a2 ("Bluetooth: hci_qca: Fix NULL vs IS_ERR_OR_NULL check in qca_serdev_probe")
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/hci_qca.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
+index 8bfef7f81b417..2acda547f4f3e 100644
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -2254,7 +2254,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
+
+ qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable",
+ GPIOD_OUT_LOW);
+- if (IS_ERR_OR_NULL(qcadev->bt_en) &&
++ if (IS_ERR(qcadev->bt_en) &&
+ (data->soc_type == QCA_WCN6750 ||
+ data->soc_type == QCA_WCN6855)) {
+ dev_err(&serdev->dev, "failed to acquire BT_EN gpio\n");
+@@ -2263,7 +2263,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
+
+ qcadev->sw_ctrl = devm_gpiod_get_optional(&serdev->dev, "swctrl",
+ GPIOD_IN);
+- if (IS_ERR_OR_NULL(qcadev->sw_ctrl) &&
++ if (IS_ERR(qcadev->sw_ctrl) &&
+ (data->soc_type == QCA_WCN6750 ||
+ data->soc_type == QCA_WCN6855 ||
+ data->soc_type == QCA_WCN7850))
+@@ -2285,7 +2285,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
+ default:
+ qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable",
+ GPIOD_OUT_LOW);
+- if (IS_ERR_OR_NULL(qcadev->bt_en)) {
++ if (IS_ERR(qcadev->bt_en)) {
+ dev_warn(&serdev->dev, "failed to acquire enable gpio\n");
+ power_ctrl_enabled = false;
+ }
+--
+2.43.0
+
--- /dev/null
+From 6216d71dcf772b6f8252d2dbb3469a1793f10d0a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Feb 2024 16:20:11 -0500
+Subject: Bluetooth: hci_sync: Fix overwriting request callback
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 2615fd9a7c2507eb3be3fbe49dcec88a2f56454a ]
+
+In a few cases the stack may generate commands as responses to events
+which would happen to overwrite the sent_cmd, so this attempts to store
+the request in req_skb so even if sent_cmd is replaced with a new
+command the pending request will remain in stored in req_skb.
+
+Fixes: 6a98e3836fa2 ("Bluetooth: Add helper for serialized HCI command execution")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_core.h | 1 +
+ net/bluetooth/hci_conn.c | 2 +-
+ net/bluetooth/hci_core.c | 46 ++++++++++++++++++++++----------
+ net/bluetooth/hci_event.c | 18 ++++++-------
+ net/bluetooth/hci_sync.c | 21 ++++++++++++---
+ 5 files changed, 61 insertions(+), 27 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index 2538f3b96623b..6bc6de5345261 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -549,6 +549,7 @@ struct hci_dev {
+ __u32 req_status;
+ __u32 req_result;
+ struct sk_buff *req_skb;
++ struct sk_buff *req_rsp;
+
+ void *smp_data;
+ void *smp_bredr_data;
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index f752a9f9bb9c7..bac5a369d2bef 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -2813,7 +2813,7 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason)
+ case HCI_EV_LE_CONN_COMPLETE:
+ case HCI_EV_LE_ENHANCED_CONN_COMPLETE:
+ case HCI_EVT_LE_CIS_ESTABLISHED:
+- hci_cmd_sync_cancel(hdev, -ECANCELED);
++ hci_cmd_sync_cancel(hdev, ECANCELED);
+ break;
+ }
+ }
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index edf7af2e13557..e0c924df13b58 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -1491,8 +1491,8 @@ static void hci_cmd_timeout(struct work_struct *work)
+ struct hci_dev *hdev = container_of(work, struct hci_dev,
+ cmd_timer.work);
+
+- if (hdev->sent_cmd) {
+- u16 opcode = hci_skb_opcode(hdev->sent_cmd);
++ if (hdev->req_skb) {
++ u16 opcode = hci_skb_opcode(hdev->req_skb);
+
+ bt_dev_err(hdev, "command 0x%4.4x tx timeout", opcode);
+
+@@ -2792,6 +2792,7 @@ void hci_release_dev(struct hci_dev *hdev)
+
+ ida_simple_remove(&hci_index_ida, hdev->id);
+ kfree_skb(hdev->sent_cmd);
++ kfree_skb(hdev->req_skb);
+ kfree_skb(hdev->recv_event);
+ kfree(hdev);
+ }
+@@ -3121,21 +3122,33 @@ int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen,
+ EXPORT_SYMBOL(__hci_cmd_send);
+
+ /* Get data from the previously sent command */
+-void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
++static void *hci_cmd_data(struct sk_buff *skb, __u16 opcode)
+ {
+ struct hci_command_hdr *hdr;
+
+- if (!hdev->sent_cmd)
++ if (!skb || skb->len < HCI_COMMAND_HDR_SIZE)
+ return NULL;
+
+- hdr = (void *) hdev->sent_cmd->data;
++ hdr = (void *)skb->data;
+
+ if (hdr->opcode != cpu_to_le16(opcode))
+ return NULL;
+
+- BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
++ return skb->data + HCI_COMMAND_HDR_SIZE;
++}
+
+- return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
++/* Get data from the previously sent command */
++void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
++{
++ void *data;
++
++ /* Check if opcode matches last sent command */
++ data = hci_cmd_data(hdev->sent_cmd, opcode);
++ if (!data)
++ /* Check if opcode matches last request */
++ data = hci_cmd_data(hdev->req_skb, opcode);
++
++ return data;
+ }
+
+ /* Get data from last received event */
+@@ -4031,17 +4044,19 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
+ if (!status && !hci_req_is_complete(hdev))
+ return;
+
++ skb = hdev->req_skb;
++
+ /* If this was the last command in a request the complete
+- * callback would be found in hdev->sent_cmd instead of the
++ * callback would be found in hdev->req_skb instead of the
+ * command queue (hdev->cmd_q).
+ */
+- if (bt_cb(hdev->sent_cmd)->hci.req_flags & HCI_REQ_SKB) {
+- *req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb;
++ if (skb && bt_cb(skb)->hci.req_flags & HCI_REQ_SKB) {
++ *req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
+ return;
+ }
+
+- if (bt_cb(hdev->sent_cmd)->hci.req_complete) {
+- *req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete;
++ if (skb && bt_cb(skb)->hci.req_complete) {
++ *req_complete = bt_cb(skb)->hci.req_complete;
+ return;
+ }
+
+@@ -4158,8 +4173,11 @@ static void hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
+ return;
+ }
+
+- if (hci_req_status_pend(hdev))
+- hci_dev_set_flag(hdev, HCI_CMD_PENDING);
++ if (hci_req_status_pend(hdev) &&
++ !hci_dev_test_and_set_flag(hdev, HCI_CMD_PENDING)) {
++ kfree_skb(hdev->req_skb);
++ hdev->req_skb = skb_clone(skb, GFP_KERNEL);
++ }
+
+ atomic_dec(&hdev->cmd_cnt);
+ }
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 0cd093ec6486c..6b746ab9f6d21 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -4329,7 +4329,7 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, void *data,
+ * (since for this kind of commands there will not be a command
+ * complete event).
+ */
+- if (ev->status || (hdev->sent_cmd && !hci_skb_event(hdev->sent_cmd))) {
++ if (ev->status || (hdev->req_skb && !hci_skb_event(hdev->req_skb))) {
+ hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete,
+ req_complete_skb);
+ if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) {
+@@ -7147,10 +7147,10 @@ static void hci_le_meta_evt(struct hci_dev *hdev, void *data,
+ bt_dev_dbg(hdev, "subevent 0x%2.2x", ev->subevent);
+
+ /* Only match event if command OGF is for LE */
+- if (hdev->sent_cmd &&
+- hci_opcode_ogf(hci_skb_opcode(hdev->sent_cmd)) == 0x08 &&
+- hci_skb_event(hdev->sent_cmd) == ev->subevent) {
+- *opcode = hci_skb_opcode(hdev->sent_cmd);
++ if (hdev->req_skb &&
++ hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) == 0x08 &&
++ hci_skb_event(hdev->req_skb) == ev->subevent) {
++ *opcode = hci_skb_opcode(hdev->req_skb);
+ hci_req_cmd_complete(hdev, *opcode, 0x00, req_complete,
+ req_complete_skb);
+ }
+@@ -7537,10 +7537,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
+ }
+
+ /* Only match event if command OGF is not for LE */
+- if (hdev->sent_cmd &&
+- hci_opcode_ogf(hci_skb_opcode(hdev->sent_cmd)) != 0x08 &&
+- hci_skb_event(hdev->sent_cmd) == event) {
+- hci_req_cmd_complete(hdev, hci_skb_opcode(hdev->sent_cmd),
++ if (hdev->req_skb &&
++ hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) != 0x08 &&
++ hci_skb_event(hdev->req_skb) == event) {
++ hci_req_cmd_complete(hdev, hci_skb_opcode(hdev->req_skb),
+ status, &req_complete, &req_complete_skb);
+ req_evt = event;
+ }
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index d0029f10d9023..65b2ad34179f8 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -31,6 +31,10 @@ static void hci_cmd_sync_complete(struct hci_dev *hdev, u8 result, u16 opcode,
+ hdev->req_result = result;
+ hdev->req_status = HCI_REQ_DONE;
+
++ /* Free the request command so it is not used as response */
++ kfree_skb(hdev->req_skb);
++ hdev->req_skb = NULL;
++
+ if (skb) {
+ struct sock *sk = hci_skb_sk(skb);
+
+@@ -38,7 +42,7 @@ static void hci_cmd_sync_complete(struct hci_dev *hdev, u8 result, u16 opcode,
+ if (sk)
+ sock_put(sk);
+
+- hdev->req_skb = skb_get(skb);
++ hdev->req_rsp = skb_get(skb);
+ }
+
+ wake_up_interruptible(&hdev->req_wait_q);
+@@ -186,8 +190,8 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
+
+ hdev->req_status = 0;
+ hdev->req_result = 0;
+- skb = hdev->req_skb;
+- hdev->req_skb = NULL;
++ skb = hdev->req_rsp;
++ hdev->req_rsp = NULL;
+
+ bt_dev_dbg(hdev, "end: err %d", err);
+
+@@ -4879,6 +4883,11 @@ int hci_dev_open_sync(struct hci_dev *hdev)
+ hdev->sent_cmd = NULL;
+ }
+
++ if (hdev->req_skb) {
++ kfree_skb(hdev->req_skb);
++ hdev->req_skb = NULL;
++ }
++
+ clear_bit(HCI_RUNNING, &hdev->flags);
+ hci_sock_dev_event(hdev, HCI_DEV_CLOSE);
+
+@@ -5040,6 +5049,12 @@ int hci_dev_close_sync(struct hci_dev *hdev)
+ hdev->sent_cmd = NULL;
+ }
+
++ /* Drop last request */
++ if (hdev->req_skb) {
++ kfree_skb(hdev->req_skb);
++ hdev->req_skb = NULL;
++ }
++
+ clear_bit(HCI_RUNNING, &hdev->flags);
+ hci_sock_dev_event(hdev, HCI_DEV_CLOSE);
+
+--
+2.43.0
+
--- /dev/null
+From 11c40705a1d0eb64d62d18ee08c56471c4696c4b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Apr 2023 11:37:55 -0700
+Subject: Bluetooth: hci_sync: Only allow hci_cmd_sync_queue if running
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit d883a4669a1def6d121ccf5e64ad28260d1c9531 ]
+
+This makes sure hci_cmd_sync_queue only queue new work if HCI_RUNNING
+has been set otherwise there is a risk of commands being sent while
+turning off.
+
+Because hci_cmd_sync_queue can no longer queue work while HCI_RUNNING is
+not set it cannot be used to power on adapters so instead
+hci_cmd_sync_submit is introduced which bypass the HCI_RUNNING check, so
+it behaves like the old implementation.
+
+Link: https://lore.kernel.org/all/CAB4PzUpDMvdc8j2MdeSAy1KkAE-D3woprCwAdYWeOc-3v3c9Sw@mail.gmail.com/
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 2615fd9a7c25 ("Bluetooth: hci_sync: Fix overwriting request callback")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_sync.h | 2 ++
+ net/bluetooth/hci_sync.c | 25 +++++++++++++++++++++++--
+ net/bluetooth/mgmt.c | 12 ++++++++----
+ 3 files changed, 33 insertions(+), 6 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
+index 17f5a4c32f36e..2fa976c466b80 100644
+--- a/include/net/bluetooth/hci_sync.h
++++ b/include/net/bluetooth/hci_sync.h
+@@ -41,6 +41,8 @@ void hci_cmd_sync_clear(struct hci_dev *hdev);
+ void hci_cmd_sync_cancel(struct hci_dev *hdev, int err);
+ void __hci_cmd_sync_cancel(struct hci_dev *hdev, int err);
+
++int hci_cmd_sync_submit(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
++ void *data, hci_cmd_sync_work_destroy_t destroy);
+ int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
+ void *data, hci_cmd_sync_work_destroy_t destroy);
+
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index a337340464567..31dd064d77a42 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -680,8 +680,12 @@ void hci_cmd_sync_cancel(struct hci_dev *hdev, int err)
+ }
+ EXPORT_SYMBOL(hci_cmd_sync_cancel);
+
+-int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
+- void *data, hci_cmd_sync_work_destroy_t destroy)
++/* Submit HCI command to be run in as cmd_sync_work:
++ *
++ * - hdev must _not_ be unregistered
++ */
++int hci_cmd_sync_submit(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
++ void *data, hci_cmd_sync_work_destroy_t destroy)
+ {
+ struct hci_cmd_sync_work_entry *entry;
+ int err = 0;
+@@ -711,6 +715,23 @@ int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
+ mutex_unlock(&hdev->unregister_lock);
+ return err;
+ }
++EXPORT_SYMBOL(hci_cmd_sync_submit);
++
++/* Queue HCI command:
++ *
++ * - hdev must be running
++ */
++int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
++ void *data, hci_cmd_sync_work_destroy_t destroy)
++{
++ /* Only queue command if hdev is running which means it had been opened
++ * and is either on init phase or is already up.
++ */
++ if (!test_bit(HCI_RUNNING, &hdev->flags))
++ return -ENETDOWN;
++
++ return hci_cmd_sync_submit(hdev, func, data, destroy);
++}
+ EXPORT_SYMBOL(hci_cmd_sync_queue);
+
+ int hci_update_eir_sync(struct hci_dev *hdev)
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index a657dc1d4ec7a..732b6cf45fbe4 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -1402,11 +1402,15 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
+ }
+
+ /* Cancel potentially blocking sync operation before power off */
+- if (cp->val == 0x00)
++ if (cp->val == 0x00) {
+ __hci_cmd_sync_cancel(hdev, -EHOSTDOWN);
+-
+- err = hci_cmd_sync_queue(hdev, set_powered_sync, cmd,
+- mgmt_set_powered_complete);
++ err = hci_cmd_sync_queue(hdev, set_powered_sync, cmd,
++ mgmt_set_powered_complete);
++ } else {
++ /* Use hci_cmd_sync_submit since hdev might not be running */
++ err = hci_cmd_sync_submit(hdev, set_powered_sync, cmd,
++ mgmt_set_powered_complete);
++ }
+
+ if (err < 0)
+ mgmt_pending_remove(cmd);
+--
+2.43.0
+
--- /dev/null
+From d3b56b2f536a8cae4cd3403caed97541fe380df2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 12:06:32 -0700
+Subject: Bluetooth: MGMT: Fix always using HCI_MAX_AD_LENGTH
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 112b5090c21905531314fee41f691f0317bbf4f6 ]
+
+HCI_MAX_AD_LENGTH shall only be used if the controller doesn't support
+extended advertising, otherwise HCI_MAX_EXT_AD_LENGTH shall be used
+instead.
+
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 2ab3e8d67fc1 ("Bluetooth: Fix eir name length")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_core.h | 4 ++++
+ net/bluetooth/hci_event.c | 12 +++++++-----
+ net/bluetooth/mgmt.c | 6 +++---
+ 3 files changed, 14 insertions(+), 8 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index 6bc6de5345261..53155cb703b5d 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -1710,6 +1710,10 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
+ /* Extended advertising support */
+ #define ext_adv_capable(dev) (((dev)->le_features[1] & HCI_LE_EXT_ADV))
+
++/* Maximum advertising length */
++#define max_adv_len(dev) \
++ (ext_adv_capable(dev) ? HCI_MAX_EXT_AD_LENGTH : HCI_MAX_AD_LENGTH)
++
+ /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E page 1789:
+ *
+ * C24: Mandatory if the LE Controller supports Connection State and either
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 6b746ab9f6d21..b150dee88f35c 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -1761,7 +1761,7 @@ static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr,
+ {
+ struct discovery_state *d = &hdev->discovery;
+
+- if (len > HCI_MAX_AD_LENGTH)
++ if (len > max_adv_len(hdev))
+ return;
+
+ bacpy(&d->last_adv_addr, bdaddr);
+@@ -6240,8 +6240,9 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
+ return;
+ }
+
+- if (!ext_adv && len > HCI_MAX_AD_LENGTH) {
+- bt_dev_err_ratelimited(hdev, "legacy adv larger than 31 bytes");
++ if (len > max_adv_len(hdev)) {
++ bt_dev_err_ratelimited(hdev,
++ "adv larger than maximum supported");
+ return;
+ }
+
+@@ -6306,7 +6307,8 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
+ */
+ conn = check_pending_le_conn(hdev, bdaddr, bdaddr_type, bdaddr_resolved,
+ type);
+- if (!ext_adv && conn && type == LE_ADV_IND && len <= HCI_MAX_AD_LENGTH) {
++ if (!ext_adv && conn && type == LE_ADV_IND &&
++ len <= max_adv_len(hdev)) {
+ /* Store report for later inclusion by
+ * mgmt_device_connected
+ */
+@@ -6447,7 +6449,7 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, void *data,
+ info->length + 1))
+ break;
+
+- if (info->length <= HCI_MAX_AD_LENGTH) {
++ if (info->length <= max_adv_len(hdev)) {
+ rssi = info->data[info->length];
+ process_adv_report(hdev, info->type, &info->bdaddr,
+ info->bdaddr_type, NULL, 0, rssi,
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 4a35535f56607..1486fb9bb78f7 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -8436,8 +8436,8 @@ static int read_adv_features(struct sock *sk, struct hci_dev *hdev,
+ supported_flags = get_supported_adv_flags(hdev);
+
+ rp->supported_flags = cpu_to_le32(supported_flags);
+- rp->max_adv_data_len = HCI_MAX_AD_LENGTH;
+- rp->max_scan_rsp_len = HCI_MAX_AD_LENGTH;
++ rp->max_adv_data_len = max_adv_len(hdev);
++ rp->max_scan_rsp_len = max_adv_len(hdev);
+ rp->max_instances = hdev->le_num_of_adv_sets;
+ rp->num_instances = hdev->adv_instance_cnt;
+
+@@ -8473,7 +8473,7 @@ static u8 calculate_name_len(struct hci_dev *hdev)
+ static u8 tlv_data_max_len(struct hci_dev *hdev, u32 adv_flags,
+ bool is_adv_data)
+ {
+- u8 max_len = HCI_MAX_AD_LENGTH;
++ u8 max_len = max_adv_len(hdev);
+
+ if (is_adv_data) {
+ if (adv_flags & (MGMT_ADV_FLAG_DISCOV |
+--
+2.43.0
+
--- /dev/null
+From bcdb413594aae0ddf65a93c520a0cc4570d2e108 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jan 2024 19:02:48 +0100
+Subject: Bluetooth: mgmt: Remove leftover queuing of power_off work
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonas Dreßler <verdre@v0yd.nl>
+
+[ Upstream commit fee054b7579fe252f8b9e6c17b9c5bfdaa84dd7e ]
+
+Queuing of power_off work was introduced in these functions with commits
+8b064a3ad377 ("Bluetooth: Clean up HCI state when doing power off") and
+c9910d0fb4fc ("Bluetooth: Fix disconnecting connections in non-connected
+states") in an effort to clean up state and do things like disconnecting
+devices before actually powering off the device.
+
+After that, commit a3172b7eb4a2 ("Bluetooth: Add timer to force power off")
+introduced a timeout to ensure that the device actually got powered off,
+even if some of the cleanup work would never complete.
+
+This code later got refactored with commit cf75ad8b41d2 ("Bluetooth:
+hci_sync: Convert MGMT_SET_POWERED"), which made powering off the device
+synchronous and removed the need for initiating the power_off work from
+other places. The timeout mentioned above got removed too, because we now
+also made use of the command timeout during power on/off.
+
+These days the power_off work still exists, but it only seems to only be
+used for HCI_AUTO_OFF functionality, which is why we never noticed
+those two leftover places where we queue power_off work. So let's remove
+that code.
+
+Fixes: cf75ad8b41d2 ("Bluetooth: hci_sync: Convert MGMT_SET_POWERED")
+Signed-off-by: Jonas Dreßler <verdre@v0yd.nl>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/mgmt.c | 16 ----------------
+ 1 file changed, 16 deletions(-)
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index ab63f807e3c80..a80bf9c42c2ef 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -9766,14 +9766,6 @@ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
+ struct mgmt_ev_device_disconnected ev;
+ struct sock *sk = NULL;
+
+- /* The connection is still in hci_conn_hash so test for 1
+- * instead of 0 to know if this is the last one.
+- */
+- if (mgmt_powering_down(hdev) && hci_conn_count(hdev) == 1) {
+- cancel_delayed_work(&hdev->power_off);
+- queue_work(hdev->req_workqueue, &hdev->power_off.work);
+- }
+-
+ if (!mgmt_connected)
+ return;
+
+@@ -9830,14 +9822,6 @@ void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
+ {
+ struct mgmt_ev_connect_failed ev;
+
+- /* The connection is still in hci_conn_hash so test for 1
+- * instead of 0 to know if this is the last one.
+- */
+- if (mgmt_powering_down(hdev) && hci_conn_count(hdev) == 1) {
+- cancel_delayed_work(&hdev->power_off);
+- queue_work(hdev->req_workqueue, &hdev->power_off.work);
+- }
+-
+ bacpy(&ev.addr.bdaddr, bdaddr);
+ ev.addr.type = link_to_bdaddr(link_type, addr_type);
+ ev.status = mgmt_status(status);
+--
+2.43.0
+
--- /dev/null
+From 5ca8741e3f2c1a021ebf40d70734d842527677a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jan 2024 19:02:47 +0100
+Subject: Bluetooth: Remove HCI_POWER_OFF_TIMEOUT
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonas Dreßler <verdre@v0yd.nl>
+
+[ Upstream commit 968667f2e0345a67a6eea5a502f4659085666564 ]
+
+With commit cf75ad8b41d2 ("Bluetooth: hci_sync: Convert MGMT_SET_POWERED"),
+the power off sequence got refactored so that this timeout was no longer
+necessary, let's remove the leftover define from the header too.
+
+Fixes: cf75ad8b41d2 ("Bluetooth: hci_sync: Convert MGMT_SET_POWERED")
+Signed-off-by: Jonas Dreßler <verdre@v0yd.nl>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci.h | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index a674221d151db..c69e09909449f 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -416,7 +416,6 @@ enum {
+ #define HCI_NCMD_TIMEOUT msecs_to_jiffies(4000) /* 4 seconds */
+ #define HCI_ACL_TX_TIMEOUT msecs_to_jiffies(45000) /* 45 seconds */
+ #define HCI_AUTO_OFF_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
+-#define HCI_POWER_OFF_TIMEOUT msecs_to_jiffies(5000) /* 5 seconds */
+ #define HCI_LE_CONN_TIMEOUT msecs_to_jiffies(20000) /* 20 seconds */
+ #define HCI_LE_AUTOCONN_TIMEOUT msecs_to_jiffies(4000) /* 4 seconds */
+
+--
+2.43.0
+
--- /dev/null
+From 788a19db69729ccf9d80637c9b7a02cf3469d542 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jan 2024 23:46:06 +0100
+Subject: Bluetooth: Remove superfluous call to hci_conn_check_pending()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jonas Dreßler <verdre@v0yd.nl>
+
+[ Upstream commit 78e3639fc8031275010c3287ac548c0bc8de83b1 ]
+
+The "pending connections" feature was originally introduced with commit
+4c67bc74f016 ("[Bluetooth] Support concurrent connect requests") and
+6bd57416127e ("[Bluetooth] Handling pending connect attempts after
+inquiry") to handle controllers supporting only a single connection request
+at a time. Later things were extended to also cancel ongoing inquiries on
+connect() with commit 89e65975fea5 ("Bluetooth: Cancel Inquiry before
+Create Connection").
+
+With commit a9de9248064b ("[Bluetooth] Switch from OGF+OCF to using only
+opcodes"), hci_conn_check_pending() was introduced as a helper to
+consolidate a few places where we check for pending connections (indicated
+by the BT_CONNECT2 flag) and then try to connect.
+
+This refactoring commit also snuck in two more calls to
+hci_conn_check_pending():
+
+- One is in the failure callback of hci_cs_inquiry(), this one probably
+makes sense: If we send an "HCI Inquiry" command and then immediately
+after a "Create Connection" command, the "Create Connection" command might
+fail before the "HCI Inquiry" command, and then we want to retry the
+"Create Connection" on failure of the "HCI Inquiry".
+
+- The other added call to hci_conn_check_pending() is in the event handler
+for the "Remote Name" event, this seems unrelated and is possibly a
+copy-paste error, so remove that one.
+
+Fixes: a9de9248064b ("[Bluetooth] Switch from OGF+OCF to using only opcodes")
+Signed-off-by: Jonas Dreßler <verdre@v0yd.nl>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 452d839c152fc..0cd093ec6486c 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -3567,8 +3567,6 @@ static void hci_remote_name_evt(struct hci_dev *hdev, void *data,
+
+ bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
+
+- hci_conn_check_pending(hdev);
+-
+ hci_dev_lock(hdev);
+
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
+--
+2.43.0
+
--- /dev/null
+From 8e930f866ee3073886b5076e3eb35547c7566789 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Feb 2024 15:32:20 -0800
+Subject: bpf: don't infer PTR_TO_CTX for programs with unnamed context type
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit 879bbe7aa4afa80acf72a1cad7f52416ea78c52d ]
+
+For program types that don't have named context type name (e.g., BPF
+iterator programs or tracepoint programs), ctx_tname will be a non-NULL
+empty string. For such programs it shouldn't be possible to have
+PTR_TO_CTX argument for global subprogs based on type name alone.
+arg:ctx tag is the only way to have PTR_TO_CTX passed into global
+subprog for such program types.
+
+Fix this loophole, which currently would assume PTR_TO_CTX whenever
+user uses a pointer to anonymous struct as an argument to their global
+subprogs. This happens in practice with the following (quite common, in
+practice) approach:
+
+typedef struct { /* anonymous */
+ int x;
+} my_type_t;
+
+int my_subprog(my_type_t *arg) { ... }
+
+User's intent is to have PTR_TO_MEM argument for `arg`, but verifier
+will complain about expecting PTR_TO_CTX.
+
+This fix also closes unintended s390x-specific KPROBE handling of
+PTR_TO_CTX case. Selftest change is necessary to accommodate this.
+
+Fixes: 91cc1a99740e ("bpf: Annotate context types")
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/r/20240212233221.2575350-4-andrii@kernel.org
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/btf.c | 3 +++
+ .../bpf/progs/test_global_func_ctx_args.c | 19 +++++++++++++++++++
+ 2 files changed, 22 insertions(+)
+
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index 7582ec4fd4131..73c36ff758b5e 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -5135,6 +5135,9 @@ btf_get_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf,
+ bpf_log(log, "Please fix kernel include/linux/bpf_types.h\n");
+ return NULL;
+ }
++ /* program types without named context types work only with arg:ctx tag */
++ if (ctx_tname[0] == '\0')
++ return false;
+ /* only compare that prog's ctx type name is the same as
+ * kernel expects. No need to compare field by field.
+ * It's ok for bpf prog to do:
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func_ctx_args.c b/tools/testing/selftests/bpf/progs/test_global_func_ctx_args.c
+index 7faa8eef0598b..144d30e654ad2 100644
+--- a/tools/testing/selftests/bpf/progs/test_global_func_ctx_args.c
++++ b/tools/testing/selftests/bpf/progs/test_global_func_ctx_args.c
+@@ -26,6 +26,23 @@ int kprobe_typedef_ctx(void *ctx)
+ return kprobe_typedef_ctx_subprog(ctx);
+ }
+
++/* s390x defines:
++ *
++ * typedef user_pt_regs bpf_user_pt_regs_t;
++ * typedef struct { ... } user_pt_regs;
++ *
++ * And so "canonical" underlying struct type is anonymous.
++ * So on s390x only valid ways to have PTR_TO_CTX argument in global subprogs
++ * are:
++ * - bpf_user_pt_regs_t *ctx (typedef);
++ * - struct bpf_user_pt_regs_t *ctx (backwards compatible struct hack);
++ * - void *ctx __arg_ctx (arg:ctx tag)
++ *
++ * Other architectures also allow using underlying struct types (e.g.,
++ * `struct pt_regs *ctx` for x86-64)
++ */
++#ifndef bpf_target_s390
++
+ #define pt_regs_struct_t typeof(*(__PT_REGS_CAST((struct pt_regs *)NULL)))
+
+ __weak int kprobe_struct_ctx_subprog(pt_regs_struct_t *ctx)
+@@ -40,6 +57,8 @@ int kprobe_resolved_ctx(void *ctx)
+ return kprobe_struct_ctx_subprog(ctx);
+ }
+
++#endif
++
+ /* this is current hack to make this work on old kernels */
+ struct bpf_user_pt_regs_t {};
+
+--
+2.43.0
+
--- /dev/null
+From e171a7b3109261460b39b0b43e5d8132297a1d01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 13:03:35 +0100
+Subject: bpf: Fix DEVMAP_HASH overflow check on 32-bit arches
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Toke Høiland-Jørgensen <toke@redhat.com>
+
+[ Upstream commit 281d464a34f540de166cee74b723e97ac2515ec3 ]
+
+The devmap code allocates a number hash buckets equal to the next power
+of two of the max_entries value provided when creating the map. When
+rounding up to the next power of two, the 32-bit variable storing the
+number of buckets can overflow, and the code checks for overflow by
+checking if the truncated 32-bit value is equal to 0. However, on 32-bit
+arches the rounding up itself can overflow mid-way through, because it
+ends up doing a left-shift of 32 bits on an unsigned long value. If the
+size of an unsigned long is four bytes, this is undefined behaviour, so
+there is no guarantee that we'll end up with a nice and tidy 0-value at
+the end.
+
+Syzbot managed to turn this into a crash on arm32 by creating a
+DEVMAP_HASH with max_entries > 0x80000000 and then trying to update it.
+Fix this by moving the overflow check to before the rounding up
+operation.
+
+Fixes: 6f9d451ab1a3 ("xdp: Add devmap_hash map type for looking up devices by hashed index")
+Link: https://lore.kernel.org/r/000000000000ed666a0611af6818@google.com
+Reported-and-tested-by: syzbot+8cd36f6b65f3cafd400a@syzkaller.appspotmail.com
+Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Message-ID: <20240307120340.99577-2-toke@redhat.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/devmap.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
+index f9a87dcc5535b..e051cbb07dac0 100644
+--- a/kernel/bpf/devmap.c
++++ b/kernel/bpf/devmap.c
+@@ -131,13 +131,14 @@ static int dev_map_init_map(struct bpf_dtab *dtab, union bpf_attr *attr)
+ bpf_map_init_from_attr(&dtab->map, attr);
+
+ if (attr->map_type == BPF_MAP_TYPE_DEVMAP_HASH) {
+- dtab->n_buckets = roundup_pow_of_two(dtab->map.max_entries);
+-
+- if (!dtab->n_buckets) /* Overflow check */
++ /* hash table size must be power of 2; roundup_pow_of_two() can
++ * overflow into UB on 32-bit arches, so check that first
++ */
++ if (dtab->map.max_entries > 1UL << 31)
+ return -EINVAL;
+- }
+
+- if (attr->map_type == BPF_MAP_TYPE_DEVMAP_HASH) {
++ dtab->n_buckets = roundup_pow_of_two(dtab->map.max_entries);
++
+ dtab->dev_index_head = dev_map_create_hash(dtab->n_buckets,
+ dtab->map.numa_node);
+ if (!dtab->dev_index_head)
+--
+2.43.0
+
--- /dev/null
+From 4661bdfa48f1dae0aa5b66bcdbbd7a12d23aa833 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 13:03:36 +0100
+Subject: bpf: Fix hashtab overflow check on 32-bit arches
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Toke Høiland-Jørgensen <toke@redhat.com>
+
+[ Upstream commit 6787d916c2cf9850c97a0a3f73e08c43e7d973b1 ]
+
+The hashtab code relies on roundup_pow_of_two() to compute the number of
+hash buckets, and contains an overflow check by checking if the
+resulting value is 0. However, on 32-bit arches, the roundup code itself
+can overflow by doing a 32-bit left-shift of an unsigned long value,
+which is undefined behaviour, so it is not guaranteed to truncate
+neatly. This was triggered by syzbot on the DEVMAP_HASH type, which
+contains the same check, copied from the hashtab code. So apply the same
+fix to hashtab, by moving the overflow check to before the roundup.
+
+Fixes: daaf427c6ab3 ("bpf: fix arraymap NULL deref and missing overflow and zero size checks")
+Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Message-ID: <20240307120340.99577-3-toke@redhat.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/hashtab.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
+index 88c71de0a0a95..0c74cc9012d5c 100644
+--- a/kernel/bpf/hashtab.c
++++ b/kernel/bpf/hashtab.c
+@@ -495,7 +495,13 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr)
+ num_possible_cpus());
+ }
+
+- /* hash table size must be power of 2 */
++ /* hash table size must be power of 2; roundup_pow_of_two() can overflow
++ * into UB on 32-bit arches, so check that first
++ */
++ err = -E2BIG;
++ if (htab->map.max_entries > 1UL << 31)
++ goto free_htab;
++
+ htab->n_buckets = roundup_pow_of_two(htab->map.max_entries);
+
+ htab->elem_size = sizeof(struct htab_elem) +
+@@ -505,10 +511,8 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr)
+ else
+ htab->elem_size += round_up(htab->map.value_size, 8);
+
+- err = -E2BIG;
+- /* prevent zero size kmalloc and check for u32 overflow */
+- if (htab->n_buckets == 0 ||
+- htab->n_buckets > U32_MAX / sizeof(struct bucket))
++ /* check for u32 overflow */
++ if (htab->n_buckets > U32_MAX / sizeof(struct bucket))
+ goto free_htab;
+
+ err = -ENOMEM;
+--
+2.43.0
+
--- /dev/null
+From 7715867ed9b32cf4a4ee5814d68d943de9b28a41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 13:03:37 +0100
+Subject: bpf: Fix stackmap overflow check on 32-bit arches
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Toke Høiland-Jørgensen <toke@redhat.com>
+
+[ Upstream commit 7a4b21250bf79eef26543d35bd390448646c536b ]
+
+The stackmap code relies on roundup_pow_of_two() to compute the number
+of hash buckets, and contains an overflow check by checking if the
+resulting value is 0. However, on 32-bit arches, the roundup code itself
+can overflow by doing a 32-bit left-shift of an unsigned long value,
+which is undefined behaviour, so it is not guaranteed to truncate
+neatly. This was triggered by syzbot on the DEVMAP_HASH type, which
+contains the same check, copied from the hashtab code.
+
+The commit in the fixes tag actually attempted to fix this, but the fix
+did not account for the UB, so the fix only works on CPUs where an
+overflow does result in a neat truncation to zero, which is not
+guaranteed. Checking the value before rounding does not have this
+problem.
+
+Fixes: 6183f4d3a0a2 ("bpf: Check for integer overflow when using roundup_pow_of_two()")
+Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Reviewed-by: Bui Quang Minh <minhquangbui99@gmail.com>
+Message-ID: <20240307120340.99577-4-toke@redhat.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/stackmap.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c
+index f86db3cf72123..f0fd936cef319 100644
+--- a/kernel/bpf/stackmap.c
++++ b/kernel/bpf/stackmap.c
+@@ -94,11 +94,14 @@ static struct bpf_map *stack_map_alloc(union bpf_attr *attr)
+ } else if (value_size / 8 > sysctl_perf_event_max_stack)
+ return ERR_PTR(-EINVAL);
+
+- /* hash table size must be power of 2 */
+- n_buckets = roundup_pow_of_two(attr->max_entries);
+- if (!n_buckets)
++ /* hash table size must be power of 2; roundup_pow_of_two() can overflow
++ * into UB on 32-bit arches, so check that first
++ */
++ if (attr->max_entries > 1UL << 31)
+ return ERR_PTR(-E2BIG);
+
++ n_buckets = roundup_pow_of_two(attr->max_entries);
++
+ cost = n_buckets * sizeof(struct stack_map_bucket *) + sizeof(*smap);
+ smap = bpf_map_area_alloc(cost, bpf_map_attr_numa_node(attr));
+ if (!smap)
+--
+2.43.0
+
--- /dev/null
+From b0db48dea99221e57e8bd69f6a64b8c504ef890b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Mar 2024 12:27:22 +0000
+Subject: bpf: hardcode BPF_PROG_PACK_SIZE to 2MB * num_possible_nodes()
+
+From: Puranjay Mohan <puranjay12@gmail.com>
+
+[ Upstream commit d6170e4aaf86424c24ce06e355b4573daa891b17 ]
+
+On some architectures like ARM64, PMD_SIZE can be really large in some
+configurations. Like with CONFIG_ARM64_64K_PAGES=y the PMD_SIZE is
+512MB.
+
+Use 2MB * num_possible_nodes() as the size for allocations done through
+the prog pack allocator. On most architectures, PMD_SIZE will be equal
+to 2MB in case of 4KB pages and will be greater than 2MB for bigger page
+sizes.
+
+Fixes: ea2babac63d4 ("bpf: Simplify bpf_prog_pack_[size|mask]")
+Reported-by: "kernelci.org bot" <bot@kernelci.org>
+Closes: https://lore.kernel.org/all/7e216c88-77ee-47b8-becc-a0f780868d3c@sirena.org.uk/
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202403092219.dhgcuz2G-lkp@intel.com/
+Suggested-by: Song Liu <song@kernel.org>
+Signed-off-by: Puranjay Mohan <puranjay12@gmail.com>
+Message-ID: <20240311122722.86232-1-puranjay12@gmail.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/core.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
+index 76bf1de261152..44abf88e1bb0d 100644
+--- a/kernel/bpf/core.c
++++ b/kernel/bpf/core.c
+@@ -857,7 +857,12 @@ static LIST_HEAD(pack_list);
+ * CONFIG_MMU=n. Use PAGE_SIZE in these cases.
+ */
+ #ifdef PMD_SIZE
+-#define BPF_PROG_PACK_SIZE (PMD_SIZE * num_possible_nodes())
++/* PMD_SIZE is really big for some archs. It doesn't make sense to
++ * reserve too much memory in one allocation. Hardcode BPF_PROG_PACK_SIZE to
++ * 2MiB * num_possible_nodes(). On most architectures PMD_SIZE will be
++ * greater than or equal to 2MB.
++ */
++#define BPF_PROG_PACK_SIZE (SZ_2M * num_possible_nodes())
+ #else
+ #define BPF_PROG_PACK_SIZE PAGE_SIZE
+ #endif
+--
+2.43.0
+
--- /dev/null
+From bd729068db1804435c6fe4615d4e0735412d7ce7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Feb 2024 23:01:02 -0800
+Subject: bpf: Mark bpf_spin_{lock,unlock}() helpers with notrace correctly
+
+From: Yonghong Song <yonghong.song@linux.dev>
+
+[ Upstream commit 178c54666f9c4d2f49f2ea661d0c11b52f0ed190 ]
+
+Currently tracing is supposed not to allow for bpf_spin_{lock,unlock}()
+helper calls. This is to prevent deadlock for the following cases:
+ - there is a prog (prog-A) calling bpf_spin_{lock,unlock}().
+ - there is a tracing program (prog-B), e.g., fentry, attached
+ to bpf_spin_lock() and/or bpf_spin_unlock().
+ - prog-B calls bpf_spin_{lock,unlock}().
+For such a case, when prog-A calls bpf_spin_{lock,unlock}(),
+a deadlock will happen.
+
+The related source codes are below in kernel/bpf/helpers.c:
+ notrace BPF_CALL_1(bpf_spin_lock, struct bpf_spin_lock *, lock)
+ notrace BPF_CALL_1(bpf_spin_unlock, struct bpf_spin_lock *, lock)
+notrace is supposed to prevent fentry prog from attaching to
+bpf_spin_{lock,unlock}().
+
+But actually this is not the case and fentry prog can successfully
+attached to bpf_spin_lock(). Siddharth Chintamaneni reported
+the issue in [1]. The following is the macro definition for
+above BPF_CALL_1:
+ #define BPF_CALL_x(x, name, ...) \
+ static __always_inline \
+ u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__)); \
+ typedef u64 (*btf_##name)(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__)); \
+ u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__)); \
+ u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__)) \
+ { \
+ return ((btf_##name)____##name)(__BPF_MAP(x,__BPF_CAST,__BPF_N,__VA_ARGS__));\
+ } \
+ static __always_inline \
+ u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__))
+
+ #define BPF_CALL_1(name, ...) BPF_CALL_x(1, name, __VA_ARGS__)
+
+The notrace attribute is actually applied to the static always_inline function
+____bpf_spin_{lock,unlock}(). The actual callback function
+bpf_spin_{lock,unlock}() is not marked with notrace, hence
+allowing fentry prog to attach to two helpers, and this
+may cause the above mentioned deadlock. Siddharth Chintamaneni
+actually has a reproducer in [2].
+
+To fix the issue, a new macro NOTRACE_BPF_CALL_1 is introduced which
+will add notrace attribute to the original function instead of
+the hidden always_inline function and this fixed the problem.
+
+ [1] https://lore.kernel.org/bpf/CAE5sdEigPnoGrzN8WU7Tx-h-iFuMZgW06qp0KHWtpvoXxf1OAQ@mail.gmail.com/
+ [2] https://lore.kernel.org/bpf/CAE5sdEg6yUc_Jz50AnUXEEUh6O73yQ1Z6NV2srJnef0ZrQkZew@mail.gmail.com/
+
+Fixes: d83525ca62cf ("bpf: introduce bpf_spin_lock")
+Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Jiri Olsa <jolsa@kernel.org>
+Link: https://lore.kernel.org/bpf/20240207070102.335167-1-yonghong.song@linux.dev
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/filter.h | 21 ++++++++++++---------
+ kernel/bpf/helpers.c | 4 ++--
+ 2 files changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/include/linux/filter.h b/include/linux/filter.h
+index efc42a6e3aed0..face590b24e17 100644
+--- a/include/linux/filter.h
++++ b/include/linux/filter.h
+@@ -495,24 +495,27 @@ static inline bool insn_is_zext(const struct bpf_insn *insn)
+ __BPF_MAP(n, __BPF_DECL_ARGS, __BPF_N, u64, __ur_1, u64, __ur_2, \
+ u64, __ur_3, u64, __ur_4, u64, __ur_5)
+
+-#define BPF_CALL_x(x, name, ...) \
++#define BPF_CALL_x(x, attr, name, ...) \
+ static __always_inline \
+ u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__)); \
+ typedef u64 (*btf_##name)(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__)); \
+- u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__)); \
+- u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__)) \
++ attr u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__)); \
++ attr u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__)) \
+ { \
+ return ((btf_##name)____##name)(__BPF_MAP(x,__BPF_CAST,__BPF_N,__VA_ARGS__));\
+ } \
+ static __always_inline \
+ u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__))
+
+-#define BPF_CALL_0(name, ...) BPF_CALL_x(0, name, __VA_ARGS__)
+-#define BPF_CALL_1(name, ...) BPF_CALL_x(1, name, __VA_ARGS__)
+-#define BPF_CALL_2(name, ...) BPF_CALL_x(2, name, __VA_ARGS__)
+-#define BPF_CALL_3(name, ...) BPF_CALL_x(3, name, __VA_ARGS__)
+-#define BPF_CALL_4(name, ...) BPF_CALL_x(4, name, __VA_ARGS__)
+-#define BPF_CALL_5(name, ...) BPF_CALL_x(5, name, __VA_ARGS__)
++#define __NOATTR
++#define BPF_CALL_0(name, ...) BPF_CALL_x(0, __NOATTR, name, __VA_ARGS__)
++#define BPF_CALL_1(name, ...) BPF_CALL_x(1, __NOATTR, name, __VA_ARGS__)
++#define BPF_CALL_2(name, ...) BPF_CALL_x(2, __NOATTR, name, __VA_ARGS__)
++#define BPF_CALL_3(name, ...) BPF_CALL_x(3, __NOATTR, name, __VA_ARGS__)
++#define BPF_CALL_4(name, ...) BPF_CALL_x(4, __NOATTR, name, __VA_ARGS__)
++#define BPF_CALL_5(name, ...) BPF_CALL_x(5, __NOATTR, name, __VA_ARGS__)
++
++#define NOTRACE_BPF_CALL_1(name, ...) BPF_CALL_x(1, notrace, name, __VA_ARGS__)
+
+ #define bpf_ctx_range(TYPE, MEMBER) \
+ offsetof(TYPE, MEMBER) ... offsetofend(TYPE, MEMBER) - 1
+diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
+index 83f8f67e933df..758510b46d87b 100644
+--- a/kernel/bpf/helpers.c
++++ b/kernel/bpf/helpers.c
+@@ -328,7 +328,7 @@ static inline void __bpf_spin_lock_irqsave(struct bpf_spin_lock *lock)
+ __this_cpu_write(irqsave_flags, flags);
+ }
+
+-notrace BPF_CALL_1(bpf_spin_lock, struct bpf_spin_lock *, lock)
++NOTRACE_BPF_CALL_1(bpf_spin_lock, struct bpf_spin_lock *, lock)
+ {
+ __bpf_spin_lock_irqsave(lock);
+ return 0;
+@@ -350,7 +350,7 @@ static inline void __bpf_spin_unlock_irqrestore(struct bpf_spin_lock *lock)
+ local_irq_restore(flags);
+ }
+
+-notrace BPF_CALL_1(bpf_spin_unlock, struct bpf_spin_lock *, lock)
++NOTRACE_BPF_CALL_1(bpf_spin_unlock, struct bpf_spin_lock *, lock)
+ {
+ __bpf_spin_unlock_irqrestore(lock);
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From 19a419ffae0a9451433063fb05e25e66ab5a7f99 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Jan 2024 14:19:20 +0800
+Subject: bpftool: Silence build warning about calloc()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Tiezhu Yang <yangtiezhu@loongson.cn>
+
+[ Upstream commit f5f30386c78105cba520e443a6a9ee945ec1d066 ]
+
+There exists the following warning when building bpftool:
+
+ CC prog.o
+prog.c: In function ‘profile_open_perf_events’:
+prog.c:2301:24: warning: ‘calloc’ sizes specified with ‘sizeof’ in the earlier argument and not in the later argument [-Wcalloc-transposed-args]
+ 2301 | sizeof(int), obj->rodata->num_cpu * obj->rodata->num_metric);
+ | ^~~
+prog.c:2301:24: note: earlier argument should specify number of elements, later size of each element
+
+Tested with the latest upstream GCC which contains a new warning option
+-Wcalloc-transposed-args. The first argument to calloc is documented to
+be number of elements in array, while the second argument is size of each
+element, just switch the first and second arguments of calloc() to silence
+the build warning, compile tested only.
+
+Fixes: 47c09d6a9f67 ("bpftool: Introduce "prog profile" command")
+Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Quentin Monnet <quentin@isovalent.com>
+Link: https://lore.kernel.org/bpf/20240116061920.31172-1-yangtiezhu@loongson.cn
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/bpftool/prog.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
+index 41c02b6f6f043..7e0b846e17eef 100644
+--- a/tools/bpf/bpftool/prog.c
++++ b/tools/bpf/bpftool/prog.c
+@@ -2200,7 +2200,7 @@ static int profile_open_perf_events(struct profiler_bpf *obj)
+ int map_fd;
+
+ profile_perf_events = calloc(
+- sizeof(int), obj->rodata->num_cpu * obj->rodata->num_metric);
++ obj->rodata->num_cpu * obj->rodata->num_metric, sizeof(int));
+ if (!profile_perf_events) {
+ p_err("failed to allocate memory for perf_event array: %s",
+ strerror(errno));
+--
+2.43.0
+
--- /dev/null
+From fa19f7551536f0b2bdaafb7bdf4891814bb3b104 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Feb 2024 10:02:37 +0000
+Subject: bus: tegra-aconnect: Update dependency to ARCH_TEGRA
+
+From: Peter Robinson <pbrobinson@gmail.com>
+
+[ Upstream commit 4acd21a45c1446277e2abaece97d7fa7c2e692a9 ]
+
+Update the architecture dependency to be the generic Tegra
+because the driver works on the four latest Tegra generations
+not just Tegra210, if you build a kernel with a specific
+ARCH_TEGRA_xxx_SOC option that excludes Tegra210 you don't get
+this driver.
+
+Fixes: 46a88534afb59 ("bus: Add support for Tegra ACONNECT")
+Signed-off-by: Peter Robinson <pbrobinson@gmail.com>
+Cc: Jon Hunter <jonathanh@nvidia.com>
+Cc: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/Kconfig | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
+index 7bfe998f3514a..bdc7633905504 100644
+--- a/drivers/bus/Kconfig
++++ b/drivers/bus/Kconfig
+@@ -186,11 +186,12 @@ config SUNXI_RSB
+
+ config TEGRA_ACONNECT
+ tristate "Tegra ACONNECT Bus Driver"
+- depends on ARCH_TEGRA_210_SOC
++ depends on ARCH_TEGRA
+ depends on OF && PM
+ help
+ Driver for the Tegra ACONNECT bus which is used to interface with
+- the devices inside the Audio Processing Engine (APE) for Tegra210.
++ the devices inside the Audio Processing Engine (APE) for
++ Tegra210 and later.
+
+ config TEGRA_GMI
+ tristate "Tegra Generic Memory Interface bus driver"
+--
+2.43.0
+
--- /dev/null
+From fa9dfbd5098b214da81a34989eacfaa233db9256 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Mar 2024 00:52:14 +0000
+Subject: clk: Fix clk_core_get NULL dereference
+
+From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+
+[ Upstream commit e97fe4901e0f59a0bfd524578fe3768f8ca42428 ]
+
+It is possible for clk_core_get to dereference a NULL in the following
+sequence:
+
+clk_core_get()
+ of_clk_get_hw_from_clkspec()
+ __of_clk_get_hw_from_provider()
+ __clk_get_hw()
+
+__clk_get_hw() can return NULL which is dereferenced by clk_core_get() at
+hw->core.
+
+Prior to commit dde4eff47c82 ("clk: Look for parents with clkdev based
+clk_lookups") the check IS_ERR_OR_NULL() was performed which would have
+caught the NULL.
+
+Reading the description of this function it talks about returning NULL but
+that cannot be so at the moment.
+
+Update the function to check for hw before dereferencing it and return NULL
+if hw is NULL.
+
+Fixes: dde4eff47c82 ("clk: Look for parents with clkdev based clk_lookups")
+Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Link: https://lore.kernel.org/r/20240302-linux-next-24-03-01-simple-clock-fixes-v1-1-25f348a5982b@linaro.org
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/clk.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index 33fedbd096f33..9004e07182259 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -407,6 +407,9 @@ static struct clk_core *clk_core_get(struct clk_core *core, u8 p_index)
+ if (IS_ERR(hw))
+ return ERR_CAST(hw);
+
++ if (!hw)
++ return NULL;
++
+ return hw->core;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 84c4b194ebaf3d49d35d17cf79f13b087996dc78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jan 2024 19:58:21 +0100
+Subject: clk: hisilicon: hi3519: Release the correct number of gates in
+ hi3519_clk_unregister()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 74e39f526d95c0c119ada1874871ee328c59fbee ]
+
+The gates are stored in 'hi3519_gate_clks', not 'hi3519_mux_clks'.
+This is also in line with how hisi_clk_register_gate() is called in the
+probe.
+
+Fixes: 224b3b262c52 ("clk: hisilicon: hi3519: add driver remove path and fix some issues")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/c3f1877c9a0886fa35c949c8f0ef25547f284f18.1704912510.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/hisilicon/clk-hi3519.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/hisilicon/clk-hi3519.c b/drivers/clk/hisilicon/clk-hi3519.c
+index ad0c7f350cf03..60d8a27a90824 100644
+--- a/drivers/clk/hisilicon/clk-hi3519.c
++++ b/drivers/clk/hisilicon/clk-hi3519.c
+@@ -130,7 +130,7 @@ static void hi3519_clk_unregister(struct platform_device *pdev)
+ of_clk_del_provider(pdev->dev.of_node);
+
+ hisi_clk_unregister_gate(hi3519_gate_clks,
+- ARRAY_SIZE(hi3519_mux_clks),
++ ARRAY_SIZE(hi3519_gate_clks),
+ crg->clk_data);
+ hisi_clk_unregister_mux(hi3519_mux_clks,
+ ARRAY_SIZE(hi3519_mux_clks),
+--
+2.43.0
+
--- /dev/null
+From 1636142f6c99009a9f4bd89faa4bba6980f37cac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Jan 2024 16:16:24 +0100
+Subject: clk: hisilicon: hi3559a: Fix an erroneous devm_kfree()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 64c6a38136b74a2f18c42199830975edd9fbc379 ]
+
+'p_clk' is an array allocated just before the for loop for all clk that
+need to be registered.
+It is incremented at each loop iteration.
+
+If a clk_register() call fails, 'p_clk' may point to something different
+from what should be freed.
+
+The best we can do, is to avoid this wrong release of memory.
+
+Fixes: 6c81966107dc ("clk: hisilicon: Add clock driver for hi3559A SoC")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/773fc8425c3b8f5b0ca7c1d89f15b65831a85ca9.1705850155.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/hisilicon/clk-hi3559a.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/clk/hisilicon/clk-hi3559a.c b/drivers/clk/hisilicon/clk-hi3559a.c
+index 9ea1a80acbe8b..0272276550ff1 100644
+--- a/drivers/clk/hisilicon/clk-hi3559a.c
++++ b/drivers/clk/hisilicon/clk-hi3559a.c
+@@ -491,7 +491,6 @@ static void hisi_clk_register_pll(struct hi3559av100_pll_clock *clks,
+
+ clk = clk_register(NULL, &p_clk->hw);
+ if (IS_ERR(clk)) {
+- devm_kfree(dev, p_clk);
+ dev_err(dev, "%s: failed to register clock %s\n",
+ __func__, clks[i].name);
+ continue;
+--
+2.43.0
+
--- /dev/null
+From 5b1a50fe067c94b37faad6a64ab9b692927a440f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Feb 2024 17:25:48 +0300
+Subject: clk: meson: Add missing clocks to axg_clk_regmaps
+
+From: Igor Prusov <ivprusov@salutedevices.com>
+
+[ Upstream commit ba535bce57e71463a86f8b33a0ea88c26e3a6418 ]
+
+Some clocks were missing from axg_clk_regmaps, which caused kernel panic
+during cat /sys/kernel/debug/clk/clk_summary
+
+[ 57.349402] Unable to handle kernel NULL pointer dereference at virtual address 00000000000001fc
+...
+[ 57.430002] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+[ 57.436900] pc : regmap_read+0x1c/0x88
+[ 57.440608] lr : clk_regmap_gate_is_enabled+0x3c/0xb0
+[ 57.445611] sp : ffff800082f1b690
+[ 57.448888] x29: ffff800082f1b690 x28: 0000000000000000 x27: ffff800080eb9a70
+[ 57.455961] x26: 0000000000000007 x25: 0000000000000016 x24: 0000000000000000
+[ 57.463033] x23: ffff800080e8b488 x22: 0000000000000015 x21: ffff00000e7e7000
+[ 57.470106] x20: ffff00000400ec00 x19: 0000000000000000 x18: ffffffffffffffff
+[ 57.477178] x17: 0000000000000000 x16: 0000000000000000 x15: ffff0000042a3000
+[ 57.484251] x14: 0000000000000000 x13: ffff0000042a2fec x12: 0000000005f5e100
+[ 57.491323] x11: abcc77118461cefd x10: 0000000000000020 x9 : ffff8000805e4b24
+[ 57.498396] x8 : ffff0000028063c0 x7 : ffff800082f1b710 x6 : ffff800082f1b710
+[ 57.505468] x5 : 00000000ffffffd0 x4 : ffff800082f1b6e0 x3 : 0000000000001000
+[ 57.512541] x2 : ffff800082f1b6e4 x1 : 000000000000012c x0 : 0000000000000000
+[ 57.519615] Call trace:
+[ 57.522030] regmap_read+0x1c/0x88
+[ 57.525393] clk_regmap_gate_is_enabled+0x3c/0xb0
+[ 57.530050] clk_core_is_enabled+0x44/0x120
+[ 57.534190] clk_summary_show_subtree+0x154/0x2f0
+[ 57.538847] clk_summary_show_subtree+0x220/0x2f0
+[ 57.543505] clk_summary_show_subtree+0x220/0x2f0
+[ 57.548162] clk_summary_show_subtree+0x220/0x2f0
+[ 57.552820] clk_summary_show_subtree+0x220/0x2f0
+[ 57.557477] clk_summary_show_subtree+0x220/0x2f0
+[ 57.562135] clk_summary_show_subtree+0x220/0x2f0
+[ 57.566792] clk_summary_show_subtree+0x220/0x2f0
+[ 57.571450] clk_summary_show+0x84/0xb8
+[ 57.575245] seq_read_iter+0x1bc/0x4b8
+[ 57.578954] seq_read+0x8c/0xd0
+[ 57.582059] full_proxy_read+0x68/0xc8
+[ 57.585767] vfs_read+0xb0/0x268
+[ 57.588959] ksys_read+0x70/0x108
+[ 57.592236] __arm64_sys_read+0x24/0x38
+[ 57.596031] invoke_syscall+0x50/0x128
+[ 57.599740] el0_svc_common.constprop.0+0x48/0xf8
+[ 57.604397] do_el0_svc+0x28/0x40
+[ 57.607675] el0_svc+0x34/0xb8
+[ 57.610694] el0t_64_sync_handler+0x13c/0x158
+[ 57.615006] el0t_64_sync+0x190/0x198
+[ 57.618635] Code: a9bd7bfd 910003fd a90153f3 aa0003f3 (b941fc00)
+[ 57.624668] ---[ end trace 0000000000000000 ]---
+
+[jbrunet: add missing Fixes tag]
+Signed-off-by: Igor Prusov <ivprusov@salutedevices.com>
+Link: https://lore.kernel.org/r/20240202172537.1.I64656c75d84284bc91e6126b50b33c502be7c42a@changeid
+Fixes: 14ebb3154b8f ("clk: meson: axg: add Video Clocks")
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/meson/axg.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
+index 2ad3801398dc1..7802dabb26f6d 100644
+--- a/drivers/clk/meson/axg.c
++++ b/drivers/clk/meson/axg.c
+@@ -2144,7 +2144,9 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
+ &axg_vclk_input,
+ &axg_vclk2_input,
+ &axg_vclk_div,
++ &axg_vclk_div1,
+ &axg_vclk2_div,
++ &axg_vclk2_div1,
+ &axg_vclk_div2_en,
+ &axg_vclk_div4_en,
+ &axg_vclk_div6_en,
+--
+2.43.0
+
--- /dev/null
+From 405e19447afa0affcdce8f6216d2357daa7b838d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jan 2024 21:20:18 +0100
+Subject: clk: qcom: dispcc-sdm845: Adjust internal GDSC wait times
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 117e7dc697c2739d754db8fe0c1e2d4f1f5d5f82 ]
+
+SDM845 downstream uses non-default values for GDSC internal waits.
+Program them accordingly to avoid surprises.
+
+Fixes: 81351776c9fb ("clk: qcom: Add display clock controller driver for SDM845")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Tested-by: Caleb Connolly <caleb.connolly@linaro.org> # OnePlus 6
+Link: https://lore.kernel.org/r/20240103-topic-845gdsc-v1-1-368efbe1a61d@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/dispcc-sdm845.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/qcom/dispcc-sdm845.c b/drivers/clk/qcom/dispcc-sdm845.c
+index 735adfefc3798..e792e0b130d33 100644
+--- a/drivers/clk/qcom/dispcc-sdm845.c
++++ b/drivers/clk/qcom/dispcc-sdm845.c
+@@ -759,6 +759,8 @@ static struct clk_branch disp_cc_mdss_vsync_clk = {
+
+ static struct gdsc mdss_gdsc = {
+ .gdscr = 0x3000,
++ .en_few_wait_val = 0x6,
++ .en_rest_wait_val = 0x5,
+ .pd = {
+ .name = "mdss_gdsc",
+ },
+--
+2.43.0
+
--- /dev/null
+From e6ed421454ac4a68547d7115314ee8b412fff350 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jan 2024 12:37:27 +0530
+Subject: clk: qcom: gcc-sc8180x: Add missing UFS QREF clocks
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit bb5c0229285fb12a5f433b2b8c5fd0ec2e4795e2 ]
+
+Add missing QREF clocks for UFS MEM and UFS CARD controllers.
+
+Fixes: 4433594bbe5d ("clk: qcom: gcc: Add global clock controller driver for SC8180x")
+Acked-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20240131-ufs-phy-clock-v3-4-58a49d2f4605@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-sc8180x.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/drivers/clk/qcom/gcc-sc8180x.c b/drivers/clk/qcom/gcc-sc8180x.c
+index c41b9f0105853..b421f67221dc1 100644
+--- a/drivers/clk/qcom/gcc-sc8180x.c
++++ b/drivers/clk/qcom/gcc-sc8180x.c
+@@ -3348,6 +3348,19 @@ static struct clk_branch gcc_ufs_card_2_unipro_core_clk = {
+ },
+ };
+
++static struct clk_branch gcc_ufs_card_clkref_en = {
++ .halt_reg = 0x8c004,
++ .halt_check = BRANCH_HALT,
++ .clkr = {
++ .enable_reg = 0x8c004,
++ .enable_mask = BIT(0),
++ .hw.init = &(const struct clk_init_data) {
++ .name = "gcc_ufs_card_clkref_en",
++ .ops = &clk_branch2_ops,
++ },
++ },
++};
++
+ static struct clk_branch gcc_ufs_card_ahb_clk = {
+ .halt_reg = 0x75014,
+ .halt_check = BRANCH_HALT,
+@@ -3562,6 +3575,19 @@ static struct clk_branch gcc_ufs_card_unipro_core_hw_ctl_clk = {
+ },
+ };
+
++static struct clk_branch gcc_ufs_mem_clkref_en = {
++ .halt_reg = 0x8c000,
++ .halt_check = BRANCH_HALT,
++ .clkr = {
++ .enable_reg = 0x8c000,
++ .enable_mask = BIT(0),
++ .hw.init = &(const struct clk_init_data) {
++ .name = "gcc_ufs_mem_clkref_en",
++ .ops = &clk_branch2_ops,
++ },
++ },
++};
++
+ static struct clk_branch gcc_ufs_phy_ahb_clk = {
+ .halt_reg = 0x77014,
+ .halt_check = BRANCH_HALT,
+@@ -4414,6 +4440,7 @@ static struct clk_regmap *gcc_sc8180x_clocks[] = {
+ [GCC_UFS_CARD_2_TX_SYMBOL_0_CLK] = &gcc_ufs_card_2_tx_symbol_0_clk.clkr,
+ [GCC_UFS_CARD_2_UNIPRO_CORE_CLK] = &gcc_ufs_card_2_unipro_core_clk.clkr,
+ [GCC_UFS_CARD_2_UNIPRO_CORE_CLK_SRC] = &gcc_ufs_card_2_unipro_core_clk_src.clkr,
++ [GCC_UFS_CARD_CLKREF_EN] = &gcc_ufs_card_clkref_en.clkr,
+ [GCC_UFS_CARD_AHB_CLK] = &gcc_ufs_card_ahb_clk.clkr,
+ [GCC_UFS_CARD_AXI_CLK] = &gcc_ufs_card_axi_clk.clkr,
+ [GCC_UFS_CARD_AXI_CLK_SRC] = &gcc_ufs_card_axi_clk_src.clkr,
+@@ -4430,6 +4457,7 @@ static struct clk_regmap *gcc_sc8180x_clocks[] = {
+ [GCC_UFS_CARD_UNIPRO_CORE_CLK] = &gcc_ufs_card_unipro_core_clk.clkr,
+ [GCC_UFS_CARD_UNIPRO_CORE_CLK_SRC] = &gcc_ufs_card_unipro_core_clk_src.clkr,
+ [GCC_UFS_CARD_UNIPRO_CORE_HW_CTL_CLK] = &gcc_ufs_card_unipro_core_hw_ctl_clk.clkr,
++ [GCC_UFS_MEM_CLKREF_EN] = &gcc_ufs_mem_clkref_en.clkr,
+ [GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr,
+ [GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr,
+ [GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr,
+--
+2.43.0
+
--- /dev/null
+From 4a3bf122ff832fdcb74a1fa50231892f0c77cbe4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Feb 2024 19:43:35 +0100
+Subject: clk: qcom: reset: Commonize the de/assert functions
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit eda40d9c583e95e0b6ac69d2950eec10f802e0e8 ]
+
+They do the same thing, except the last argument of the last function
+call differs. Commonize them.
+
+Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20240105-topic-venus_reset-v2-2-c37eba13b5ce@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: 2f8cf2c3f3e3 ("clk: qcom: reset: Ensure write completion on reset de/assertion")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/reset.c | 22 +++++++++-------------
+ 1 file changed, 9 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/clk/qcom/reset.c b/drivers/clk/qcom/reset.c
+index e45e32804d2c7..20d1d35aaf229 100644
+--- a/drivers/clk/qcom/reset.c
++++ b/drivers/clk/qcom/reset.c
+@@ -22,8 +22,8 @@ static int qcom_reset(struct reset_controller_dev *rcdev, unsigned long id)
+ return 0;
+ }
+
+-static int
+-qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
++static int qcom_reset_set_assert(struct reset_controller_dev *rcdev,
++ unsigned long id, bool assert)
+ {
+ struct qcom_reset_controller *rst;
+ const struct qcom_reset_map *map;
+@@ -33,21 +33,17 @@ qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
+ map = &rst->reset_map[id];
+ mask = map->bitmask ? map->bitmask : BIT(map->bit);
+
+- return regmap_update_bits(rst->regmap, map->reg, mask, mask);
++ return regmap_update_bits(rst->regmap, map->reg, mask, assert ? mask : 0);
+ }
+
+-static int
+-qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
++static int qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
+ {
+- struct qcom_reset_controller *rst;
+- const struct qcom_reset_map *map;
+- u32 mask;
+-
+- rst = to_qcom_reset_controller(rcdev);
+- map = &rst->reset_map[id];
+- mask = map->bitmask ? map->bitmask : BIT(map->bit);
++ return qcom_reset_set_assert(rcdev, id, true);
++}
+
+- return regmap_update_bits(rst->regmap, map->reg, mask, 0);
++static int qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
++{
++ return qcom_reset_set_assert(rcdev, id, false);
+ }
+
+ const struct reset_control_ops qcom_reset_ops = {
+--
+2.43.0
+
--- /dev/null
+From 6dac80b6e2d5c0e4b3d573d976a0cb34f7a8fac1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Feb 2024 19:43:36 +0100
+Subject: clk: qcom: reset: Ensure write completion on reset de/assertion
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit 2f8cf2c3f3e3f7ef61bd19abb4b0bb797ad50aaf ]
+
+Trying to toggle the resets in a rapid fashion can lead to the changes
+not actually arriving at the clock controller block when we expect them
+to. This was observed at least on SM8250.
+
+Read back the value after regmap_update_bits to ensure write completion.
+
+Fixes: b36ba30c8ac6 ("clk: qcom: Add reset controller support")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20240105-topic-venus_reset-v2-3-c37eba13b5ce@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/reset.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/qcom/reset.c b/drivers/clk/qcom/reset.c
+index 20d1d35aaf229..d96c96a9089f4 100644
+--- a/drivers/clk/qcom/reset.c
++++ b/drivers/clk/qcom/reset.c
+@@ -33,7 +33,12 @@ static int qcom_reset_set_assert(struct reset_controller_dev *rcdev,
+ map = &rst->reset_map[id];
+ mask = map->bitmask ? map->bitmask : BIT(map->bit);
+
+- return regmap_update_bits(rst->regmap, map->reg, mask, assert ? mask : 0);
++ regmap_update_bits(rst->regmap, map->reg, mask, assert ? mask : 0);
++
++ /* Read back the register to ensure write completion, ignore the value */
++ regmap_read(rst->regmap, map->reg, &mask);
++
++ return 0;
+ }
+
+ static int qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
+--
+2.43.0
+
--- /dev/null
+From ac01ce3d3464ff9d55f2e7bdecd4a0f9f059b793 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Jan 2024 16:45:13 +0100
+Subject: clk: renesas: r8a779f0: Correct PFC/GPIO parent clock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit d1b32a83a02d9433dbd8c5f4d6fc44aa597755bd ]
+
+According to the R-Car S4 Series Hardware User’s Manual Rev.0.81, the
+parent clock of the Pin Function (PFC/GPIO) module clock is the CP
+clock.
+
+As this clock is not documented to exist on R-Car S4, use the CPEX clock
+instead.
+
+Fixes: 73421f2a48e6bd1d ("clk: renesas: r8a779f0: Add PFC clock")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/f88ec4aede0eaf0107c8bb7b28ba719ac6cd418f.1706197415.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/renesas/r8a779f0-cpg-mssr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/renesas/r8a779f0-cpg-mssr.c b/drivers/clk/renesas/r8a779f0-cpg-mssr.c
+index 27b668def357f..7a49b91c93710 100644
+--- a/drivers/clk/renesas/r8a779f0-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a779f0-cpg-mssr.c
+@@ -159,7 +159,7 @@ static const struct mssr_mod_clk r8a779f0_mod_clks[] __initconst = {
+ DEF_MOD("cmt1", 911, R8A779F0_CLK_R),
+ DEF_MOD("cmt2", 912, R8A779F0_CLK_R),
+ DEF_MOD("cmt3", 913, R8A779F0_CLK_R),
+- DEF_MOD("pfc0", 915, R8A779F0_CLK_CL16M),
++ DEF_MOD("pfc0", 915, R8A779F0_CLK_CPEX),
+ DEF_MOD("tsc", 919, R8A779F0_CLK_CL16M),
+ DEF_MOD("ufs", 1514, R8A779F0_CLK_S0D4_HSC),
+ };
+--
+2.43.0
+
--- /dev/null
+From 0d49eb47dbd06c044b360f4c5f4e10a11bea0105 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 01:03:24 +0000
+Subject: clk: renesas: r8a779g0: Add Audio clocks
+
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+
+[ Upstream commit 8dffb520ace48bcb996db049540c78261730213c ]
+
+Add module clocks for the Audio (SSI/SSIU) blocks on the Renesas R-Car
+V4H (R8A779G0) SoC.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/878rhganfo.wl-kuninori.morimoto.gx@renesas.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Stable-dep-of: abb3fa662b8f ("clk: renesas: r8a779g0: Correct PFC/GPIO parent clocks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/renesas/r8a779g0-cpg-mssr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a779g0-cpg-mssr.c b/drivers/clk/renesas/r8a779g0-cpg-mssr.c
+index f89cda70f2cbb..d0e8deacdd0be 100644
+--- a/drivers/clk/renesas/r8a779g0-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a779g0-cpg-mssr.c
+@@ -177,6 +177,8 @@ static const struct mssr_mod_clk r8a779g0_mod_clks[] __initconst = {
+ DEF_MOD("pfc1", 916, R8A779G0_CLK_CL16M),
+ DEF_MOD("pfc2", 917, R8A779G0_CLK_CL16M),
+ DEF_MOD("pfc3", 918, R8A779G0_CLK_CL16M),
++ DEF_MOD("ssiu", 2926, R8A779G0_CLK_S0D6_PER),
++ DEF_MOD("ssi", 2927, R8A779G0_CLK_S0D6_PER),
+ };
+
+ /*
+--
+2.43.0
+
--- /dev/null
+From 91cb30da2d57ec27d01abc9d92865d71723542d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Nov 2022 16:11:33 +0100
+Subject: clk: renesas: r8a779g0: Add CMT clocks
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit 523ed9442b997c39220ee364b07a8773623e3a58 ]
+
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Link: https://lore.kernel.org/r/20221104151135.4706-2-wsa+renesas@sang-engineering.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Stable-dep-of: abb3fa662b8f ("clk: renesas: r8a779g0: Correct PFC/GPIO parent clocks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/renesas/r8a779g0-cpg-mssr.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a779g0-cpg-mssr.c b/drivers/clk/renesas/r8a779g0-cpg-mssr.c
+index d5b325e3c5398..f89cda70f2cbb 100644
+--- a/drivers/clk/renesas/r8a779g0-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a779g0-cpg-mssr.c
+@@ -169,6 +169,10 @@ static const struct mssr_mod_clk r8a779g0_mod_clks[] __initconst = {
+ DEF_MOD("i2c4", 522, R8A779G0_CLK_S0D6_PER),
+ DEF_MOD("i2c5", 523, R8A779G0_CLK_S0D6_PER),
+ DEF_MOD("wdt1:wdt0", 907, R8A779G0_CLK_R),
++ DEF_MOD("cmt0", 910, R8A779G0_CLK_R),
++ DEF_MOD("cmt1", 911, R8A779G0_CLK_R),
++ DEF_MOD("cmt2", 912, R8A779G0_CLK_R),
++ DEF_MOD("cmt3", 913, R8A779G0_CLK_R),
+ DEF_MOD("pfc0", 915, R8A779G0_CLK_CL16M),
+ DEF_MOD("pfc1", 916, R8A779G0_CLK_CL16M),
+ DEF_MOD("pfc2", 917, R8A779G0_CLK_CL16M),
+--
+2.43.0
+
--- /dev/null
+From 1006f4626f26efac90b7983b36725cfc2f60a7d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Feb 2023 17:03:00 +0100
+Subject: clk: renesas: r8a779g0: Add thermal clock
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 7502a04dae0e614bc14553e31461e50499bc67aa ]
+
+Add the module clock used by the Thermal Sensor/Chip Internal Voltage
+Monitor/Core Voltage Monitor (THS/CIVM/CVM) on the Renesas R-Car V4H
+(R8A779G0) SoC.
+
+Based on a large patch in the BSP by Kazuya Mizuguchi.
+
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Link: https://lore.kernel.org/r/59461effd0d9f7a39e0c91352c87f2b7071b1891.1675958536.git.geert+renesas@glider.be
+Stable-dep-of: abb3fa662b8f ("clk: renesas: r8a779g0: Correct PFC/GPIO parent clocks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/renesas/r8a779g0-cpg-mssr.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/renesas/r8a779g0-cpg-mssr.c b/drivers/clk/renesas/r8a779g0-cpg-mssr.c
+index d0e8deacdd0be..aace98c0c4735 100644
+--- a/drivers/clk/renesas/r8a779g0-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a779g0-cpg-mssr.c
+@@ -177,6 +177,7 @@ static const struct mssr_mod_clk r8a779g0_mod_clks[] __initconst = {
+ DEF_MOD("pfc1", 916, R8A779G0_CLK_CL16M),
+ DEF_MOD("pfc2", 917, R8A779G0_CLK_CL16M),
+ DEF_MOD("pfc3", 918, R8A779G0_CLK_CL16M),
++ DEF_MOD("tsc", 919, R8A779G0_CLK_CL16M),
+ DEF_MOD("ssiu", 2926, R8A779G0_CLK_S0D6_PER),
+ DEF_MOD("ssi", 2927, R8A779G0_CLK_S0D6_PER),
+ };
+--
+2.43.0
+
--- /dev/null
+From 5a438a1dece5208347aaaa9d2116887b8c2017f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Jan 2024 16:43:26 +0100
+Subject: clk: renesas: r8a779g0: Correct PFC/GPIO parent clocks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit abb3fa662b8f8eaed1590b0e7a4e19eda467cdd3 ]
+
+According to the R-Car V4H Series Hardware User’s Manual Rev.1.00, the
+parent clock of the Pin Function (PFC/GPIO) module clocks is the CP
+clock.
+
+Fix this by adding the missing CP clock, and correcting the PFC parents.
+
+Fixes: f2afa78d5a0c0b0b ("dt-bindings: clock: Add r8a779g0 CPG Core Clock Definitions")
+Fixes: 36ff366033f0dde1 ("clk: renesas: r8a779g0: Add PFC/GPIO clocks")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/5401fccd204dc90b44f0013e7f53b9eff8df8214.1706197297.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/renesas/r8a779g0-cpg-mssr.c | 11 ++++++-----
+ include/dt-bindings/clock/r8a779g0-cpg-mssr.h | 1 +
+ 2 files changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/clk/renesas/r8a779g0-cpg-mssr.c b/drivers/clk/renesas/r8a779g0-cpg-mssr.c
+index aace98c0c4735..e4c616921e5ea 100644
+--- a/drivers/clk/renesas/r8a779g0-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a779g0-cpg-mssr.c
+@@ -22,7 +22,7 @@
+
+ enum clk_ids {
+ /* Core Clock Outputs exported to DT */
+- LAST_DT_CORE_CLK = R8A779G0_CLK_R,
++ LAST_DT_CORE_CLK = R8A779G0_CLK_CP,
+
+ /* External Input Clocks */
+ CLK_EXTAL,
+@@ -139,6 +139,7 @@ static const struct cpg_core_clk r8a779g0_core_clks[] __initconst = {
+ DEF_FIXED("svd2_vip", R8A779G0_CLK_SVD2_VIP, CLK_SV_VIP, 2, 1),
+ DEF_FIXED("cbfusa", R8A779G0_CLK_CBFUSA, CLK_EXTAL, 2, 1),
+ DEF_FIXED("cpex", R8A779G0_CLK_CPEX, CLK_EXTAL, 2, 1),
++ DEF_FIXED("cp", R8A779G0_CLK_CP, CLK_EXTAL, 2, 1),
+ DEF_FIXED("viobus", R8A779G0_CLK_VIOBUS, CLK_VIO, 1, 1),
+ DEF_FIXED("viobusd2", R8A779G0_CLK_VIOBUSD2, CLK_VIO, 2, 1),
+ DEF_FIXED("vcbus", R8A779G0_CLK_VCBUS, CLK_VC, 1, 1),
+@@ -173,10 +174,10 @@ static const struct mssr_mod_clk r8a779g0_mod_clks[] __initconst = {
+ DEF_MOD("cmt1", 911, R8A779G0_CLK_R),
+ DEF_MOD("cmt2", 912, R8A779G0_CLK_R),
+ DEF_MOD("cmt3", 913, R8A779G0_CLK_R),
+- DEF_MOD("pfc0", 915, R8A779G0_CLK_CL16M),
+- DEF_MOD("pfc1", 916, R8A779G0_CLK_CL16M),
+- DEF_MOD("pfc2", 917, R8A779G0_CLK_CL16M),
+- DEF_MOD("pfc3", 918, R8A779G0_CLK_CL16M),
++ DEF_MOD("pfc0", 915, R8A779G0_CLK_CP),
++ DEF_MOD("pfc1", 916, R8A779G0_CLK_CP),
++ DEF_MOD("pfc2", 917, R8A779G0_CLK_CP),
++ DEF_MOD("pfc3", 918, R8A779G0_CLK_CP),
+ DEF_MOD("tsc", 919, R8A779G0_CLK_CL16M),
+ DEF_MOD("ssiu", 2926, R8A779G0_CLK_S0D6_PER),
+ DEF_MOD("ssi", 2927, R8A779G0_CLK_S0D6_PER),
+diff --git a/include/dt-bindings/clock/r8a779g0-cpg-mssr.h b/include/dt-bindings/clock/r8a779g0-cpg-mssr.h
+index 754c54a6eb06a..7850cdc62e285 100644
+--- a/include/dt-bindings/clock/r8a779g0-cpg-mssr.h
++++ b/include/dt-bindings/clock/r8a779g0-cpg-mssr.h
+@@ -86,5 +86,6 @@
+ #define R8A779G0_CLK_CPEX 74
+ #define R8A779G0_CLK_CBFUSA 75
+ #define R8A779G0_CLK_R 76
++#define R8A779G0_CLK_CP 77
+
+ #endif /* __DT_BINDINGS_CLOCK_R8A779G0_CPG_MSSR_H__ */
+--
+2.43.0
+
--- /dev/null
+From 5ac249b610d37b13d73c5462ae640cb52939c454 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jan 2024 19:38:56 -0600
+Subject: clk: samsung: exynos850: Propagate SPI IPCLK rate change
+
+From: Sam Protsenko <semen.protsenko@linaro.org>
+
+[ Upstream commit 67c15187d4910ee353374676d4dddf09d8cb227e ]
+
+When SPI transfer is being prepared, the spi-s3c64xx driver will call
+clk_set_rate() to change the rate of SPI source clock (IPCLK). But IPCLK
+is a gate (leaf) clock, so it must propagate the rate change up the
+clock tree, so that corresponding DIV clocks can actually change their
+divider values. Add CLK_SET_RATE_PARENT flag to corresponding clocks for
+all SPI instances in Exynos850 (spi_0, spi_1 and spi_2) to make it
+possible. This change involves next clocks:
+
+usi_spi_0:
+
+ Clock Block Div range
+ --------------------------------------------
+ gout_spi0_ipclk CMU_PERI -
+ dout_peri_spi0 CMU_PERI /1..32
+ mout_peri_spi_user CMU_PERI -
+ dout_peri_ip CMU_TOP /1..16
+
+usi_cmgp0:
+
+ Clock Block Div range
+ --------------------------------------------
+ gout_cmgp_usi0_ipclk CMU_CMGP -
+ dout_cmgp_usi0 CMU_CMGP /1..32
+ mout_cmgp_usi0 CMU_CMGP -
+ gout_clkcmu_cmgp_bus CMU_APM -
+ dout_apm_bus CMU_APM /1..8
+
+usi_cmgp1:
+
+ Clock Block Div range
+ --------------------------------------------
+ gout_cmgp_usi1_ipclk CMU_CMGP -
+ dout_cmgp_usi1 CMU_CMGP /1..32
+ mout_cmgp_usi1 CMU_CMGP -
+ gout_clkcmu_cmgp_bus CMU_APM -
+ dout_apm_bus CMU_APM /1..8
+
+With input clock of 400 MHz, this scheme provides next IPCLK rate range,
+for each SPI block:
+
+ SPI0: 781 kHz ... 400 MHz
+ SPI1/2: 1.6 MHz ... 400 MHz
+
+Accounting for internal /4 divider in SPI blocks, and because the max
+SPI frequency is limited at 50 MHz, it gives us next SPI SCK rates:
+
+ SPI0: 200 kHz ... 49.9 MHz
+ SPI1/2: 400 kHz ... 49.9 MHz
+
+Which should cover all possible applications of SPI bus. Of course,
+setting SPI frequency to values as low as 500 kHz will also affect the
+common bus dividers (dout_apm_bus or dout_peri_ip), which in turn
+effectively lowers the rates for all leaf bus clocks derived from those
+dividers, like HSI2C and I3C clocks. But at least it gives the board
+designer a choice, whether to keep all clocks (SPI/HSI2C/I3C) at high
+frequencies, or make all those clocks have lower frequencies. Not
+propagating the rate change to those common dividers would limit this
+choice to "only high frequencies are allowed for SPI/HSI2C/I3C" option,
+making the common dividers useless. This decision follows the "Worse is
+better" approach, relying on the users/engineers to know the system
+internals when working with such low-level features, instead of trying
+to account for all possible use-cases.
+
+Fixes: 7dd05578198b ("clk: samsung: Introduce Exynos850 clock driver")
+Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
+Reviewed-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Link: https://lore.kernel.org/r/20240125013858.3986-2-semen.protsenko@linaro.org
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/samsung/clk-exynos850.c | 33 +++++++++++++++--------------
+ 1 file changed, 17 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/clk/samsung/clk-exynos850.c b/drivers/clk/samsung/clk-exynos850.c
+index 541761e96aeb6..87e463ad42741 100644
+--- a/drivers/clk/samsung/clk-exynos850.c
++++ b/drivers/clk/samsung/clk-exynos850.c
+@@ -572,7 +572,7 @@ static const struct samsung_div_clock apm_div_clks[] __initconst = {
+
+ static const struct samsung_gate_clock apm_gate_clks[] __initconst = {
+ GATE(CLK_GOUT_CLKCMU_CMGP_BUS, "gout_clkcmu_cmgp_bus", "dout_apm_bus",
+- CLK_CON_GAT_CLKCMU_CMGP_BUS, 21, 0, 0),
++ CLK_CON_GAT_CLKCMU_CMGP_BUS, 21, CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_CLKCMU_CHUB_BUS, "gout_clkcmu_chub_bus",
+ "mout_clkcmu_chub_bus",
+ CLK_CON_GAT_GATE_CLKCMU_CHUB_BUS, 21, 0, 0),
+@@ -936,19 +936,19 @@ static const struct samsung_fixed_rate_clock cmgp_fixed_clks[] __initconst = {
+ static const struct samsung_mux_clock cmgp_mux_clks[] __initconst = {
+ MUX(CLK_MOUT_CMGP_ADC, "mout_cmgp_adc", mout_cmgp_adc_p,
+ CLK_CON_MUX_CLK_CMGP_ADC, 0, 1),
+- MUX(CLK_MOUT_CMGP_USI0, "mout_cmgp_usi0", mout_cmgp_usi0_p,
+- CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP0, 0, 1),
+- MUX(CLK_MOUT_CMGP_USI1, "mout_cmgp_usi1", mout_cmgp_usi1_p,
+- CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP1, 0, 1),
++ MUX_F(CLK_MOUT_CMGP_USI0, "mout_cmgp_usi0", mout_cmgp_usi0_p,
++ CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP0, 0, 1, CLK_SET_RATE_PARENT, 0),
++ MUX_F(CLK_MOUT_CMGP_USI1, "mout_cmgp_usi1", mout_cmgp_usi1_p,
++ CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP1, 0, 1, CLK_SET_RATE_PARENT, 0),
+ };
+
+ static const struct samsung_div_clock cmgp_div_clks[] __initconst = {
+ DIV(CLK_DOUT_CMGP_ADC, "dout_cmgp_adc", "gout_clkcmu_cmgp_bus",
+ CLK_CON_DIV_DIV_CLK_CMGP_ADC, 0, 4),
+- DIV(CLK_DOUT_CMGP_USI0, "dout_cmgp_usi0", "mout_cmgp_usi0",
+- CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP0, 0, 5),
+- DIV(CLK_DOUT_CMGP_USI1, "dout_cmgp_usi1", "mout_cmgp_usi1",
+- CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP1, 0, 5),
++ DIV_F(CLK_DOUT_CMGP_USI0, "dout_cmgp_usi0", "mout_cmgp_usi0",
++ CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP0, 0, 5, CLK_SET_RATE_PARENT, 0),
++ DIV_F(CLK_DOUT_CMGP_USI1, "dout_cmgp_usi1", "mout_cmgp_usi1",
++ CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP1, 0, 5, CLK_SET_RATE_PARENT, 0),
+ };
+
+ static const struct samsung_gate_clock cmgp_gate_clks[] __initconst = {
+@@ -963,12 +963,12 @@ static const struct samsung_gate_clock cmgp_gate_clks[] __initconst = {
+ "gout_clkcmu_cmgp_bus",
+ CLK_CON_GAT_GOUT_CMGP_GPIO_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+ GATE(CLK_GOUT_CMGP_USI0_IPCLK, "gout_cmgp_usi0_ipclk", "dout_cmgp_usi0",
+- CLK_CON_GAT_GOUT_CMGP_USI_CMGP0_IPCLK, 21, 0, 0),
++ CLK_CON_GAT_GOUT_CMGP_USI_CMGP0_IPCLK, 21, CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_CMGP_USI0_PCLK, "gout_cmgp_usi0_pclk",
+ "gout_clkcmu_cmgp_bus",
+ CLK_CON_GAT_GOUT_CMGP_USI_CMGP0_PCLK, 21, 0, 0),
+ GATE(CLK_GOUT_CMGP_USI1_IPCLK, "gout_cmgp_usi1_ipclk", "dout_cmgp_usi1",
+- CLK_CON_GAT_GOUT_CMGP_USI_CMGP1_IPCLK, 21, 0, 0),
++ CLK_CON_GAT_GOUT_CMGP_USI_CMGP1_IPCLK, 21, CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_CMGP_USI1_PCLK, "gout_cmgp_usi1_pclk",
+ "gout_clkcmu_cmgp_bus",
+ CLK_CON_GAT_GOUT_CMGP_USI_CMGP1_PCLK, 21, 0, 0),
+@@ -1409,8 +1409,9 @@ static const struct samsung_mux_clock peri_mux_clks[] __initconst = {
+ mout_peri_uart_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART_USER, 4, 1),
+ MUX(CLK_MOUT_PERI_HSI2C_USER, "mout_peri_hsi2c_user",
+ mout_peri_hsi2c_user_p, PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER, 4, 1),
+- MUX(CLK_MOUT_PERI_SPI_USER, "mout_peri_spi_user", mout_peri_spi_user_p,
+- PLL_CON0_MUX_CLKCMU_PERI_SPI_USER, 4, 1),
++ MUX_F(CLK_MOUT_PERI_SPI_USER, "mout_peri_spi_user",
++ mout_peri_spi_user_p, PLL_CON0_MUX_CLKCMU_PERI_SPI_USER, 4, 1,
++ CLK_SET_RATE_PARENT, 0),
+ };
+
+ static const struct samsung_div_clock peri_div_clks[] __initconst = {
+@@ -1420,8 +1421,8 @@ static const struct samsung_div_clock peri_div_clks[] __initconst = {
+ CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1, 0, 5),
+ DIV(CLK_DOUT_PERI_HSI2C2, "dout_peri_hsi2c2", "gout_peri_hsi2c2",
+ CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2, 0, 5),
+- DIV(CLK_DOUT_PERI_SPI0, "dout_peri_spi0", "mout_peri_spi_user",
+- CLK_CON_DIV_DIV_CLK_PERI_SPI_0, 0, 5),
++ DIV_F(CLK_DOUT_PERI_SPI0, "dout_peri_spi0", "mout_peri_spi_user",
++ CLK_CON_DIV_DIV_CLK_PERI_SPI_0, 0, 5, CLK_SET_RATE_PARENT, 0),
+ };
+
+ static const struct samsung_gate_clock peri_gate_clks[] __initconst = {
+@@ -1463,7 +1464,7 @@ static const struct samsung_gate_clock peri_gate_clks[] __initconst = {
+ "mout_peri_bus_user",
+ CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK, 21, 0, 0),
+ GATE(CLK_GOUT_SPI0_IPCLK, "gout_spi0_ipclk", "dout_peri_spi0",
+- CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK, 21, 0, 0),
++ CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK, 21, CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_GOUT_SPI0_PCLK, "gout_spi0_pclk", "mout_peri_bus_user",
+ CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK, 21, 0, 0),
+ GATE(CLK_GOUT_SYSREG_PERI_PCLK, "gout_sysreg_peri_pclk",
+--
+2.43.0
+
--- /dev/null
+From daab41b278d9ec0b7331f7c3800bc22a52a006c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Mar 2024 16:44:37 +0800
+Subject: clk: zynq: Prevent null pointer dereference caused by kmalloc failure
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+[ Upstream commit 7938e9ce39d6779d2f85d822cc930f73420e54a6 ]
+
+The kmalloc() in zynq_clk_setup() will return null if the
+physical memory has run out. As a result, if we use snprintf()
+to write data to the null address, the null pointer dereference
+bug will happen.
+
+This patch uses a stack variable to replace the kmalloc().
+
+Fixes: 0ee52b157b8e ("clk: zynq: Add clock controller driver")
+Suggested-by: Michal Simek <michal.simek@amd.com>
+Suggested-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
+Link: https://lore.kernel.org/r/20240301084437.16084-1-duoming@zju.edu.cn
+Acked-by: Michal Simek <michal.simek@amd.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/zynq/clkc.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c
+index 7bdeaff2bfd68..c28d3dacf0fb2 100644
+--- a/drivers/clk/zynq/clkc.c
++++ b/drivers/clk/zynq/clkc.c
+@@ -42,6 +42,7 @@ static void __iomem *zynq_clkc_base;
+ #define SLCR_SWDT_CLK_SEL (zynq_clkc_base + 0x204)
+
+ #define NUM_MIO_PINS 54
++#define CLK_NAME_LEN 16
+
+ #define DBG_CLK_CTRL_CLKACT_TRC BIT(0)
+ #define DBG_CLK_CTRL_CPU_1XCLKACT BIT(1)
+@@ -215,7 +216,7 @@ static void __init zynq_clk_setup(struct device_node *np)
+ int i;
+ u32 tmp;
+ int ret;
+- char *clk_name;
++ char clk_name[CLK_NAME_LEN];
+ unsigned int fclk_enable = 0;
+ const char *clk_output_name[clk_max];
+ const char *cpu_parents[4];
+@@ -426,12 +427,10 @@ static void __init zynq_clk_setup(struct device_node *np)
+ "gem1_emio_mux", CLK_SET_RATE_PARENT,
+ SLCR_GEM1_CLK_CTRL, 0, 0, &gem1clk_lock);
+
+- tmp = strlen("mio_clk_00x");
+- clk_name = kmalloc(tmp, GFP_KERNEL);
+ for (i = 0; i < NUM_MIO_PINS; i++) {
+ int idx;
+
+- snprintf(clk_name, tmp, "mio_clk_%2.2d", i);
++ snprintf(clk_name, CLK_NAME_LEN, "mio_clk_%2.2d", i);
+ idx = of_property_match_string(np, "clock-names", clk_name);
+ if (idx >= 0)
+ can_mio_mux_parents[i] = of_clk_get_parent_name(np,
+@@ -439,7 +438,6 @@ static void __init zynq_clk_setup(struct device_node *np)
+ else
+ can_mio_mux_parents[i] = dummy_nm;
+ }
+- kfree(clk_name);
+ clk_register_mux(NULL, "can_mux", periph_parents, 4,
+ CLK_SET_RATE_NO_REPARENT, SLCR_CAN_CLK_CTRL, 4, 2, 0,
+ &canclk_lock);
+--
+2.43.0
+
--- /dev/null
+From d20f47c99eaf03e54e7c5956acfdaad12755c66a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 10:12:20 +0300
+Subject: cpufreq: brcmstb-avs-cpufreq: add check for cpufreq_cpu_get's return
+ value
+
+From: Anastasia Belova <abelova@astralinux.ru>
+
+[ Upstream commit f661017e6d326ee187db24194cabb013d81bc2a6 ]
+
+cpufreq_cpu_get may return NULL. To avoid NULL-dereference check it
+and return 0 in case of error.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: de322e085995 ("cpufreq: brcmstb-avs-cpufreq: AVS CPUfreq driver for Broadcom STB SoCs")
+Signed-off-by: Anastasia Belova <abelova@astralinux.ru>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/brcmstb-avs-cpufreq.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/cpufreq/brcmstb-avs-cpufreq.c b/drivers/cpufreq/brcmstb-avs-cpufreq.c
+index f644c5e325fb2..38ec0fedb247f 100644
+--- a/drivers/cpufreq/brcmstb-avs-cpufreq.c
++++ b/drivers/cpufreq/brcmstb-avs-cpufreq.c
+@@ -481,6 +481,8 @@ static bool brcm_avs_is_firmware_loaded(struct private_data *priv)
+ static unsigned int brcm_avs_cpufreq_get(unsigned int cpu)
+ {
+ struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
++ if (!policy)
++ return 0;
+ struct private_data *priv = policy->driver_data;
+
+ cpufreq_cpu_put(policy);
+--
+2.43.0
+
--- /dev/null
+From db446ce9a8a9aea46d5ffd0288efccd7dc1313e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Jul 2023 11:44:13 -0600
+Subject: cpufreq: Explicitly include correct DT includes
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit a70eb93a2477371638ef481aaae7bb7b760d3004 ]
+
+The DT of_device.h and of_platform.h date back to the separate
+of_platform_bus_type before it as merged into the regular platform bus.
+As part of that merge prepping Arm DT support 13 years ago, they
+"temporarily" include each other. They also include platform_device.h
+and of.h. As a result, there's a pretty much random mix of those include
+files used throughout the tree. In order to detangle these headers and
+replace the implicit includes with struct declarations, users need to
+explicitly include the correct includes.
+
+Signed-off-by: Rob Herring <robh@kernel.org>
+Acked-by: Rafael J. Wysocki <rafael@kernel.org>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Stable-dep-of: 788715b5f21c ("cpufreq: mediatek-hw: Wait for CPU supplies before probing")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/armada-37xx-cpufreq.c | 4 +---
+ drivers/cpufreq/mediatek-cpufreq-hw.c | 3 ++-
+ drivers/cpufreq/ppc_cbe_cpufreq.c | 2 +-
+ drivers/cpufreq/ppc_cbe_cpufreq_pmi.c | 1 -
+ drivers/cpufreq/qcom-cpufreq-nvmem.c | 1 -
+ drivers/cpufreq/scpi-cpufreq.c | 2 +-
+ drivers/cpufreq/sti-cpufreq.c | 2 +-
+ drivers/cpufreq/ti-cpufreq.c | 2 +-
+ drivers/cpufreq/vexpress-spc-cpufreq.c | 1 -
+ 9 files changed, 7 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c
+index b74289a95a171..bea41ccabf1f0 100644
+--- a/drivers/cpufreq/armada-37xx-cpufreq.c
++++ b/drivers/cpufreq/armada-37xx-cpufreq.c
+@@ -14,10 +14,8 @@
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
+ #include <linux/mfd/syscon.h>
++#include <linux/mod_devicetable.h>
+ #include <linux/module.h>
+-#include <linux/of_address.h>
+-#include <linux/of_device.h>
+-#include <linux/of_irq.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_opp.h>
+ #include <linux/regmap.h>
+diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c b/drivers/cpufreq/mediatek-cpufreq-hw.c
+index f0e0a35c7f217..212bbca8daf32 100644
+--- a/drivers/cpufreq/mediatek-cpufreq-hw.c
++++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
+@@ -10,8 +10,9 @@
+ #include <linux/iopoll.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+-#include <linux/of_address.h>
++#include <linux/of.h>
+ #include <linux/of_platform.h>
++#include <linux/platform_device.h>
+ #include <linux/slab.h>
+
+ #define LUT_MAX_ENTRIES 32U
+diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c
+index e3313ce63b388..88afc49941b71 100644
+--- a/drivers/cpufreq/ppc_cbe_cpufreq.c
++++ b/drivers/cpufreq/ppc_cbe_cpufreq.c
+@@ -9,7 +9,7 @@
+
+ #include <linux/cpufreq.h>
+ #include <linux/module.h>
+-#include <linux/of_platform.h>
++#include <linux/of.h>
+
+ #include <asm/machdep.h>
+ #include <asm/cell-regs.h>
+diff --git a/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c b/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c
+index 4fba3637b115c..6f0c32592416d 100644
+--- a/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c
++++ b/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c
+@@ -11,7 +11,6 @@
+ #include <linux/types.h>
+ #include <linux/timer.h>
+ #include <linux/init.h>
+-#include <linux/of_platform.h>
+ #include <linux/pm_qos.h>
+ #include <linux/slab.h>
+
+diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c
+index a577586b23be2..cb03bfb0435ea 100644
+--- a/drivers/cpufreq/qcom-cpufreq-nvmem.c
++++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
+@@ -22,7 +22,6 @@
+ #include <linux/module.h>
+ #include <linux/nvmem-consumer.h>
+ #include <linux/of.h>
+-#include <linux/of_device.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_domain.h>
+ #include <linux/pm_opp.h>
+diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c
+index fd2c16821d54c..ac719aca49b75 100644
+--- a/drivers/cpufreq/scpi-cpufreq.c
++++ b/drivers/cpufreq/scpi-cpufreq.c
+@@ -14,7 +14,7 @@
+ #include <linux/cpumask.h>
+ #include <linux/export.h>
+ #include <linux/module.h>
+-#include <linux/of_platform.h>
++#include <linux/platform_device.h>
+ #include <linux/pm_opp.h>
+ #include <linux/scpi_protocol.h>
+ #include <linux/slab.h>
+diff --git a/drivers/cpufreq/sti-cpufreq.c b/drivers/cpufreq/sti-cpufreq.c
+index 1a63aeea87112..9c542e723a157 100644
+--- a/drivers/cpufreq/sti-cpufreq.c
++++ b/drivers/cpufreq/sti-cpufreq.c
+@@ -13,7 +13,7 @@
+ #include <linux/mfd/syscon.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
+-#include <linux/of_platform.h>
++#include <linux/platform_device.h>
+ #include <linux/pm_opp.h>
+ #include <linux/regmap.h>
+
+diff --git a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c
+index f64180dd2005b..61ef653bcf56f 100644
+--- a/drivers/cpufreq/ti-cpufreq.c
++++ b/drivers/cpufreq/ti-cpufreq.c
+@@ -12,7 +12,7 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/of.h>
+-#include <linux/of_platform.h>
++#include <linux/platform_device.h>
+ #include <linux/pm_opp.h>
+ #include <linux/regmap.h>
+ #include <linux/slab.h>
+diff --git a/drivers/cpufreq/vexpress-spc-cpufreq.c b/drivers/cpufreq/vexpress-spc-cpufreq.c
+index d295f405c4bb0..865e501648034 100644
+--- a/drivers/cpufreq/vexpress-spc-cpufreq.c
++++ b/drivers/cpufreq/vexpress-spc-cpufreq.c
+@@ -18,7 +18,6 @@
+ #include <linux/device.h>
+ #include <linux/module.h>
+ #include <linux/mutex.h>
+-#include <linux/of_platform.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_opp.h>
+ #include <linux/slab.h>
+--
+2.43.0
+
--- /dev/null
+From 62c109b9d2357f3976423e0c09df71594b544f46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jan 2024 17:31:43 -0300
+Subject: cpufreq: mediatek-hw: Don't error out if supply is not found
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit eaffb10b51bf74415c9252fd8fb4dd77122501ee ]
+
+devm_regulator_get_optional() returns -ENODEV if no supply can be found.
+By introducing its usage, commit 788715b5f21c ("cpufreq: mediatek-hw:
+Wait for CPU supplies before probing") caused the driver to fail probe
+if no supply was present in any of the CPU DT nodes.
+
+Use devm_regulator_get() instead since the CPUs do require supplies
+even if not described in the DT. It will gracefully return a dummy
+regulator if none is found in the DT node, allowing probe to succeed.
+
+Fixes: 788715b5f21c ("cpufreq: mediatek-hw: Wait for CPU supplies before probing")
+Reported-by: kernelci.org bot <bot@kernelci.org>
+Closes: https://linux.kernelci.org/test/case/id/65b0b169710edea22852a3fa/
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/mediatek-cpufreq-hw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c b/drivers/cpufreq/mediatek-cpufreq-hw.c
+index 42240a7d826da..7f326bb5fd8de 100644
+--- a/drivers/cpufreq/mediatek-cpufreq-hw.c
++++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
+@@ -308,7 +308,7 @@ static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev)
+ return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
+ "Failed to get cpu%d device\n", cpu);
+
+- cpu_reg = devm_regulator_get_optional(cpu_dev, "cpu");
++ cpu_reg = devm_regulator_get(cpu_dev, "cpu");
+ if (IS_ERR(cpu_reg))
+ return dev_err_probe(&pdev->dev, PTR_ERR(cpu_reg),
+ "CPU%d regulator get failed\n", cpu);
+--
+2.43.0
+
--- /dev/null
+From d44db897f9cc4236df076c3841a5726e3f7c07fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jan 2024 11:23:02 -0300
+Subject: cpufreq: mediatek-hw: Wait for CPU supplies before probing
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit 788715b5f21c6455264fe00a1779e61bec407fe2 ]
+
+Before proceeding with the probe and enabling frequency scaling for the
+CPUs, make sure that all supplies feeding the CPUs have probed.
+
+This fixes an issue observed on MT8195-Tomato where if the
+mediatek-cpufreq-hw driver enabled the hardware (by writing to
+REG_FREQ_ENABLE) before the SPMI controller driver (spmi-mtk-pmif),
+behind which lies the big CPU supply, probed the platform would hang
+shortly after with "rcu: INFO: rcu_preempt detected stalls on
+CPUs/tasks" being printed in the log.
+
+Fixes: 4855e26bcf4d ("cpufreq: mediatek-hw: Add support for CPUFREQ HW")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/mediatek-cpufreq-hw.c | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c b/drivers/cpufreq/mediatek-cpufreq-hw.c
+index 212bbca8daf32..42240a7d826da 100644
+--- a/drivers/cpufreq/mediatek-cpufreq-hw.c
++++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
+@@ -13,6 +13,7 @@
+ #include <linux/of.h>
+ #include <linux/of_platform.h>
+ #include <linux/platform_device.h>
++#include <linux/regulator/consumer.h>
+ #include <linux/slab.h>
+
+ #define LUT_MAX_ENTRIES 32U
+@@ -296,7 +297,23 @@ static struct cpufreq_driver cpufreq_mtk_hw_driver = {
+ static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev)
+ {
+ const void *data;
+- int ret;
++ int ret, cpu;
++ struct device *cpu_dev;
++ struct regulator *cpu_reg;
++
++ /* Make sure that all CPU supplies are available before proceeding. */
++ for_each_possible_cpu(cpu) {
++ cpu_dev = get_cpu_device(cpu);
++ if (!cpu_dev)
++ return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
++ "Failed to get cpu%d device\n", cpu);
++
++ cpu_reg = devm_regulator_get_optional(cpu_dev, "cpu");
++ if (IS_ERR(cpu_reg))
++ return dev_err_probe(&pdev->dev, PTR_ERR(cpu_reg),
++ "CPU%d regulator get failed\n", cpu);
++ }
++
+
+ data = of_device_get_match_data(&pdev->dev);
+ if (!data)
+--
+2.43.0
+
--- /dev/null
+From aff46441eb218b1ec9524dc7695e059306567f6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Feb 2024 14:49:46 +0100
+Subject: crypto: arm/sha - fix function cast warnings
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 53cc9baeb9bc2a187eb9c9790d30995148852b12 ]
+
+clang-16 warns about casting between incompatible function types:
+
+arch/arm/crypto/sha256_glue.c:37:5: error: cast from 'void (*)(u32 *, const void *, unsigned int)' (aka 'void (*)(unsigned int *, const void *, unsigned int)') to 'sha256_block_fn *' (aka 'void (*)(struct sha256_state *, const unsigned char *, int)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+ 37 | (sha256_block_fn *)sha256_block_data_order);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+arch/arm/crypto/sha512-glue.c:34:3: error: cast from 'void (*)(u64 *, const u8 *, int)' (aka 'void (*)(unsigned long long *, const unsigned char *, int)') to 'sha512_block_fn *' (aka 'void (*)(struct sha512_state *, const unsigned char *, int)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+ 34 | (sha512_block_fn *)sha512_block_data_order);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Fix the prototypes for the assembler functions to match the typedef.
+The code already relies on the digest being the first part of the
+state structure, so there is no change in behavior.
+
+Fixes: c80ae7ca3726 ("crypto: arm/sha512 - accelerated SHA-512 using ARM generic ASM and NEON")
+Fixes: b59e2ae3690c ("crypto: arm/sha256 - move SHA-224/256 ASM/NEON implementation to base layer")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/crypto/sha256_glue.c | 13 +++++--------
+ arch/arm/crypto/sha512-glue.c | 12 +++++-------
+ 2 files changed, 10 insertions(+), 15 deletions(-)
+
+diff --git a/arch/arm/crypto/sha256_glue.c b/arch/arm/crypto/sha256_glue.c
+index 433ee4ddce6c8..f85933fdec75f 100644
+--- a/arch/arm/crypto/sha256_glue.c
++++ b/arch/arm/crypto/sha256_glue.c
+@@ -24,8 +24,8 @@
+
+ #include "sha256_glue.h"
+
+-asmlinkage void sha256_block_data_order(u32 *digest, const void *data,
+- unsigned int num_blks);
++asmlinkage void sha256_block_data_order(struct sha256_state *state,
++ const u8 *data, int num_blks);
+
+ int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+@@ -33,23 +33,20 @@ int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data,
+ /* make sure casting to sha256_block_fn() is safe */
+ BUILD_BUG_ON(offsetof(struct sha256_state, state) != 0);
+
+- return sha256_base_do_update(desc, data, len,
+- (sha256_block_fn *)sha256_block_data_order);
++ return sha256_base_do_update(desc, data, len, sha256_block_data_order);
+ }
+ EXPORT_SYMBOL(crypto_sha256_arm_update);
+
+ static int crypto_sha256_arm_final(struct shash_desc *desc, u8 *out)
+ {
+- sha256_base_do_finalize(desc,
+- (sha256_block_fn *)sha256_block_data_order);
++ sha256_base_do_finalize(desc, sha256_block_data_order);
+ return sha256_base_finish(desc, out);
+ }
+
+ int crypto_sha256_arm_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+ {
+- sha256_base_do_update(desc, data, len,
+- (sha256_block_fn *)sha256_block_data_order);
++ sha256_base_do_update(desc, data, len, sha256_block_data_order);
+ return crypto_sha256_arm_final(desc, out);
+ }
+ EXPORT_SYMBOL(crypto_sha256_arm_finup);
+diff --git a/arch/arm/crypto/sha512-glue.c b/arch/arm/crypto/sha512-glue.c
+index 0635a65aa488b..1be5bd498af36 100644
+--- a/arch/arm/crypto/sha512-glue.c
++++ b/arch/arm/crypto/sha512-glue.c
+@@ -25,27 +25,25 @@ MODULE_ALIAS_CRYPTO("sha512");
+ MODULE_ALIAS_CRYPTO("sha384-arm");
+ MODULE_ALIAS_CRYPTO("sha512-arm");
+
+-asmlinkage void sha512_block_data_order(u64 *state, u8 const *src, int blocks);
++asmlinkage void sha512_block_data_order(struct sha512_state *state,
++ u8 const *src, int blocks);
+
+ int sha512_arm_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+ {
+- return sha512_base_do_update(desc, data, len,
+- (sha512_block_fn *)sha512_block_data_order);
++ return sha512_base_do_update(desc, data, len, sha512_block_data_order);
+ }
+
+ static int sha512_arm_final(struct shash_desc *desc, u8 *out)
+ {
+- sha512_base_do_finalize(desc,
+- (sha512_block_fn *)sha512_block_data_order);
++ sha512_base_do_finalize(desc, sha512_block_data_order);
+ return sha512_base_finish(desc, out);
+ }
+
+ int sha512_arm_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+ {
+- sha512_base_do_update(desc, data, len,
+- (sha512_block_fn *)sha512_block_data_order);
++ sha512_base_do_update(desc, data, len, sha512_block_data_order);
+ return sha512_arm_final(desc, out);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 9743f50f753d566b53a3c72cd87f0cb0eddd5e9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Feb 2024 08:55:13 -0800
+Subject: crypto: jitter - fix CRYPTO_JITTERENTROPY help text
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit e63df1ec9a16dd9e13e9068243e64876de06f795 ]
+
+Correct various small problems in the help text:
+a. change 2 spaces to ", "
+b. finish an incomplete sentence
+c. change non-working URL to working URL
+
+Fixes: a9a98d49da52 ("crypto: Kconfig - simplify compression/RNG entries")
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218458
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: Bagas Sanjaya <bagasdotme@gmail.com>
+Cc: Robert Elliott <elliott@hpe.com>
+Cc: Christoph Biedl <bugzilla.kernel.bpeb@manchmal.in-ulm.de>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: linux-crypto@vger.kernel.org
+Acked-by: Bagas Sanjaya <bagasdotme@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/Kconfig | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/crypto/Kconfig b/crypto/Kconfig
+index d779667671b23..edf193aff23e7 100644
+--- a/crypto/Kconfig
++++ b/crypto/Kconfig
+@@ -1285,10 +1285,11 @@ config CRYPTO_JITTERENTROPY
+
+ A non-physical non-deterministic ("true") RNG (e.g., an entropy source
+ compliant with NIST SP800-90B) intended to provide a seed to a
+- deterministic RNG (e.g. per NIST SP800-90C).
++ deterministic RNG (e.g., per NIST SP800-90C).
+ This RNG does not perform any cryptographic whitening of the generated
++ random numbers.
+
+- See https://www.chronox.de/jent.html
++ See https://www.chronox.de/jent/
+
+ config CRYPTO_KDF800108_CTR
+ tristate
+--
+2.43.0
+
--- /dev/null
+From fab13a07c0783fa0fd0880ad7ff6e8d8b1ff7b50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 Jan 2024 12:29:06 +0800
+Subject: crypto: xilinx - call finalize with bh disabled
+
+From: Quanyang Wang <quanyang.wang@windriver.com>
+
+[ Upstream commit a853450bf4c752e664abab0b2fad395b7ad7701c ]
+
+When calling crypto_finalize_request, BH should be disabled to avoid
+triggering the following calltrace:
+
+ ------------[ cut here ]------------
+ WARNING: CPU: 2 PID: 74 at crypto/crypto_engine.c:58 crypto_finalize_request+0xa0/0x118
+ Modules linked in: cryptodev(O)
+ CPU: 2 PID: 74 Comm: firmware:zynqmp Tainted: G O 6.8.0-rc1-yocto-standard #323
+ Hardware name: ZynqMP ZCU102 Rev1.0 (DT)
+ pstate: 40000005 (nZcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+ pc : crypto_finalize_request+0xa0/0x118
+ lr : crypto_finalize_request+0x104/0x118
+ sp : ffffffc085353ce0
+ x29: ffffffc085353ce0 x28: 0000000000000000 x27: ffffff8808ea8688
+ x26: ffffffc081715038 x25: 0000000000000000 x24: ffffff880100db00
+ x23: ffffff880100da80 x22: 0000000000000000 x21: 0000000000000000
+ x20: ffffff8805b14000 x19: ffffff880100da80 x18: 0000000000010450
+ x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
+ x14: 0000000000000003 x13: 0000000000000000 x12: ffffff880100dad0
+ x11: 0000000000000000 x10: ffffffc0832dcd08 x9 : ffffffc0812416d8
+ x8 : 00000000000001f4 x7 : ffffffc0830d2830 x6 : 0000000000000001
+ x5 : ffffffc082091000 x4 : ffffffc082091658 x3 : 0000000000000000
+ x2 : ffffffc7f9653000 x1 : 0000000000000000 x0 : ffffff8802d20000
+ Call trace:
+ crypto_finalize_request+0xa0/0x118
+ crypto_finalize_aead_request+0x18/0x30
+ zynqmp_handle_aes_req+0xcc/0x388
+ crypto_pump_work+0x168/0x2d8
+ kthread_worker_fn+0xfc/0x3a0
+ kthread+0x118/0x138
+ ret_from_fork+0x10/0x20
+ irq event stamp: 40
+ hardirqs last enabled at (39): [<ffffffc0812416f8>] _raw_spin_unlock_irqrestore+0x70/0xb0
+ hardirqs last disabled at (40): [<ffffffc08122d208>] el1_dbg+0x28/0x90
+ softirqs last enabled at (36): [<ffffffc080017dec>] kernel_neon_begin+0x8c/0xf0
+ softirqs last disabled at (34): [<ffffffc080017dc0>] kernel_neon_begin+0x60/0xf0
+ ---[ end trace 0000000000000000 ]---
+
+Fixes: 4d96f7d48131 ("crypto: xilinx - Add Xilinx AES driver")
+Signed-off-by: Quanyang Wang <quanyang.wang@windriver.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/xilinx/zynqmp-aes-gcm.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/crypto/xilinx/zynqmp-aes-gcm.c b/drivers/crypto/xilinx/zynqmp-aes-gcm.c
+index bf1f421e05f25..74bd3eb63734d 100644
+--- a/drivers/crypto/xilinx/zynqmp-aes-gcm.c
++++ b/drivers/crypto/xilinx/zynqmp-aes-gcm.c
+@@ -231,7 +231,10 @@ static int zynqmp_handle_aes_req(struct crypto_engine *engine,
+ err = zynqmp_aes_aead_cipher(areq);
+ }
+
++ local_bh_disable();
+ crypto_finalize_aead_request(engine, areq, err);
++ local_bh_enable();
++
+ return 0;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From f53aa18e1716b72bb2c12925cd7b99db317d602c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Mar 2024 15:06:39 +0100
+Subject: dm: call the resume method on internal suspend
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+[ Upstream commit 65e8fbde64520001abf1c8d0e573561b4746ef38 ]
+
+There is this reported crash when experimenting with the lvm2 testsuite.
+The list corruption is caused by the fact that the postsuspend and resume
+methods were not paired correctly; there were two consecutive calls to the
+origin_postsuspend function. The second call attempts to remove the
+"hash_list" entry from a list, while it was already removed by the first
+call.
+
+Fix __dm_internal_resume so that it calls the preresume and resume
+methods of the table's targets.
+
+If a preresume method of some target fails, we are in a tricky situation.
+We can't return an error because dm_internal_resume isn't supposed to
+return errors. We can't return success, because then the "resume" and
+"postsuspend" methods would not be paired correctly. So, we set the
+DMF_SUSPENDED flag and we fake normal suspend - it may confuse userspace
+tools, but it won't cause a kernel crash.
+
+------------[ cut here ]------------
+kernel BUG at lib/list_debug.c:56!
+invalid opcode: 0000 [#1] PREEMPT SMP
+CPU: 1 PID: 8343 Comm: dmsetup Not tainted 6.8.0-rc6 #4
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014
+RIP: 0010:__list_del_entry_valid_or_report+0x77/0xc0
+<snip>
+RSP: 0018:ffff8881b831bcc0 EFLAGS: 00010282
+RAX: 000000000000004e RBX: ffff888143b6eb80 RCX: 0000000000000000
+RDX: 0000000000000001 RSI: ffffffff819053d0 RDI: 00000000ffffffff
+RBP: ffff8881b83a3400 R08: 00000000fffeffff R09: 0000000000000058
+R10: 0000000000000000 R11: ffffffff81a24080 R12: 0000000000000001
+R13: ffff88814538e000 R14: ffff888143bc6dc0 R15: ffffffffa02e4bb0
+FS: 00000000f7c0f780(0000) GS:ffff8893f0a40000(0000) knlGS:0000000000000000
+CS: 0010 DS: 002b ES: 002b CR0: 0000000080050033
+CR2: 0000000057fb5000 CR3: 0000000143474000 CR4: 00000000000006b0
+Call Trace:
+ <TASK>
+ ? die+0x2d/0x80
+ ? do_trap+0xeb/0xf0
+ ? __list_del_entry_valid_or_report+0x77/0xc0
+ ? do_error_trap+0x60/0x80
+ ? __list_del_entry_valid_or_report+0x77/0xc0
+ ? exc_invalid_op+0x49/0x60
+ ? __list_del_entry_valid_or_report+0x77/0xc0
+ ? asm_exc_invalid_op+0x16/0x20
+ ? table_deps+0x1b0/0x1b0 [dm_mod]
+ ? __list_del_entry_valid_or_report+0x77/0xc0
+ origin_postsuspend+0x1a/0x50 [dm_snapshot]
+ dm_table_postsuspend_targets+0x34/0x50 [dm_mod]
+ dm_suspend+0xd8/0xf0 [dm_mod]
+ dev_suspend+0x1f2/0x2f0 [dm_mod]
+ ? table_deps+0x1b0/0x1b0 [dm_mod]
+ ctl_ioctl+0x300/0x5f0 [dm_mod]
+ dm_compat_ctl_ioctl+0x7/0x10 [dm_mod]
+ __x64_compat_sys_ioctl+0x104/0x170
+ do_syscall_64+0x184/0x1b0
+ entry_SYSCALL_64_after_hwframe+0x46/0x4e
+RIP: 0033:0xf7e6aead
+<snip>
+---[ end trace 0000000000000000 ]---
+
+Fixes: ffcc39364160 ("dm: enhance internal suspend and resume interface")
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm.c | 26 ++++++++++++++++++++------
+ 1 file changed, 20 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 0ec85d159bcde..29270f6f272f6 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -2897,6 +2897,9 @@ static void __dm_internal_suspend(struct mapped_device *md, unsigned int suspend
+
+ static void __dm_internal_resume(struct mapped_device *md)
+ {
++ int r;
++ struct dm_table *map;
++
+ BUG_ON(!md->internal_suspend_count);
+
+ if (--md->internal_suspend_count)
+@@ -2905,12 +2908,23 @@ static void __dm_internal_resume(struct mapped_device *md)
+ if (dm_suspended_md(md))
+ goto done; /* resume from nested suspend */
+
+- /*
+- * NOTE: existing callers don't need to call dm_table_resume_targets
+- * (which may fail -- so best to avoid it for now by passing NULL map)
+- */
+- (void) __dm_resume(md, NULL);
+-
++ map = rcu_dereference_protected(md->map, lockdep_is_held(&md->suspend_lock));
++ r = __dm_resume(md, map);
++ if (r) {
++ /*
++ * If a preresume method of some target failed, we are in a
++ * tricky situation. We can't return an error to the caller. We
++ * can't fake success because then the "resume" and
++ * "postsuspend" methods would not be paired correctly, and it
++ * would break various targets, for example it would cause list
++ * corruption in the "origin" target.
++ *
++ * So, we fake normal suspend here, to make sure that the
++ * "resume" and "postsuspend" methods will be paired correctly.
++ */
++ DMERR("Preresume method failed: %d", r);
++ set_bit(DMF_SUSPENDED, &md->flags);
++ }
+ done:
+ clear_bit(DMF_SUSPENDED_INTERNALLY, &md->flags);
+ smp_mb__after_atomic();
+--
+2.43.0
+
--- /dev/null
+From 2bb9735b4fca22d4897cbbff886a144a0ae3be4e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Mar 2024 13:42:55 -0400
+Subject: dm raid: fix false positive for requeue needed during reshape
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit b25b8f4b8ecef0f48c05f0c3572daeabefe16526 ]
+
+An empty flush doesn't have a payload, so it should never be looked at
+when considering to possibly requeue a bio for the case when a reshape
+is in progress.
+
+Fixes: 9dbd1aa3a81c ("dm raid: add reshaping support to the target")
+Reported-by: Patrick Plenefisch <simonpatp@gmail.com>
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-raid.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
+index 4b7528dc2fd08..7fbce214e00f5 100644
+--- a/drivers/md/dm-raid.c
++++ b/drivers/md/dm-raid.c
+@@ -3325,14 +3325,14 @@ static int raid_map(struct dm_target *ti, struct bio *bio)
+ struct mddev *mddev = &rs->md;
+
+ /*
+- * If we're reshaping to add disk(s)), ti->len and
++ * If we're reshaping to add disk(s), ti->len and
+ * mddev->array_sectors will differ during the process
+ * (ti->len > mddev->array_sectors), so we have to requeue
+ * bios with addresses > mddev->array_sectors here or
+ * there will occur accesses past EOD of the component
+ * data images thus erroring the raid set.
+ */
+- if (unlikely(bio_end_sector(bio) > mddev->array_sectors))
++ if (unlikely(bio_has_data(bio) && bio_end_sector(bio) > mddev->array_sectors))
+ return DM_MAPIO_REQUEUE;
+
+ md_handle_request(mddev, bio);
+--
+2.43.0
+
--- /dev/null
+From f41220d5e2a0a8758485602e7c0c55c9dc13c633 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jan 2024 09:32:56 +0000
+Subject: dmaengine: tegra210-adma: Update dependency to ARCH_TEGRA
+
+From: Peter Robinson <pbrobinson@gmail.com>
+
+[ Upstream commit 33b7db45533af240fe44e809f9dc4d604cf82d07 ]
+
+Update the architecture dependency to be the generic Tegra
+because the driver works on the four latest Tegra generations
+not just T210, if you build a kernel with a specific
+ARCH_TEGRA_xxx_SOC option that excludes 210 you don't get
+this driver.
+
+Fixes: 433de642a76c9 ("dmaengine: tegra210-adma: add support for Tegra186/Tegra194")
+Signed-off-by: Peter Robinson <pbrobinson@gmail.com>
+Cc: Jon Hunter <jonathanh@nvidia.com>
+Cc: Thierry Reding <treding@nvidia.com>
+Cc: Sameer Pujar <spujar@nvidia.com>
+Cc: Laxman Dewangan <ldewangan@nvidia.com>
+Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
+Link: https://lore.kernel.org/r/20240112093310.329642-2-pbrobinson@gmail.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/Kconfig | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
+index 81de833ccd041..66ef0a1114845 100644
+--- a/drivers/dma/Kconfig
++++ b/drivers/dma/Kconfig
+@@ -665,16 +665,16 @@ config TEGRA20_APB_DMA
+
+ config TEGRA210_ADMA
+ tristate "NVIDIA Tegra210 ADMA support"
+- depends on (ARCH_TEGRA_210_SOC || COMPILE_TEST)
++ depends on (ARCH_TEGRA || COMPILE_TEST)
+ select DMA_ENGINE
+ select DMA_VIRTUAL_CHANNELS
+ help
+- Support for the NVIDIA Tegra210 ADMA controller driver. The
+- DMA controller has multiple DMA channels and is used to service
+- various audio clients in the Tegra210 audio processing engine
+- (APE). This DMA controller transfers data from memory to
+- peripheral and vice versa. It does not support memory to
+- memory data transfer.
++ Support for the NVIDIA Tegra210/Tegra186/Tegra194/Tegra234 ADMA
++ controller driver. The DMA controller has multiple DMA channels
++ and is used to service various audio clients in the Tegra210
++ audio processing engine (APE). This DMA controller transfers
++ data from memory to peripheral and vice versa. It does not
++ support memory to memory data transfer.
+
+ config TIMB_DMA
+ tristate "Timberdale FPGA DMA support"
+--
+2.43.0
+
--- /dev/null
+From 206c353f5fbfdd1d7ccbfee90797833e06ae4afc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jan 2024 07:39:06 -0800
+Subject: do_sys_name_to_handle(): use kzalloc() to fix kernel-infoleak
+
+From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+
+[ Upstream commit 3948abaa4e2be938ccdfc289385a27342fb13d43 ]
+
+syzbot identified a kernel information leak vulnerability in
+do_sys_name_to_handle() and issued the following report [1].
+
+[1]
+"BUG: KMSAN: kernel-infoleak in instrument_copy_to_user include/linux/instrumented.h:114 [inline]
+BUG: KMSAN: kernel-infoleak in _copy_to_user+0xbc/0x100 lib/usercopy.c:40
+ instrument_copy_to_user include/linux/instrumented.h:114 [inline]
+ _copy_to_user+0xbc/0x100 lib/usercopy.c:40
+ copy_to_user include/linux/uaccess.h:191 [inline]
+ do_sys_name_to_handle fs/fhandle.c:73 [inline]
+ __do_sys_name_to_handle_at fs/fhandle.c:112 [inline]
+ __se_sys_name_to_handle_at+0x949/0xb10 fs/fhandle.c:94
+ __x64_sys_name_to_handle_at+0xe4/0x140 fs/fhandle.c:94
+ ...
+
+Uninit was created at:
+ slab_post_alloc_hook+0x129/0xa70 mm/slab.h:768
+ slab_alloc_node mm/slub.c:3478 [inline]
+ __kmem_cache_alloc_node+0x5c9/0x970 mm/slub.c:3517
+ __do_kmalloc_node mm/slab_common.c:1006 [inline]
+ __kmalloc+0x121/0x3c0 mm/slab_common.c:1020
+ kmalloc include/linux/slab.h:604 [inline]
+ do_sys_name_to_handle fs/fhandle.c:39 [inline]
+ __do_sys_name_to_handle_at fs/fhandle.c:112 [inline]
+ __se_sys_name_to_handle_at+0x441/0xb10 fs/fhandle.c:94
+ __x64_sys_name_to_handle_at+0xe4/0x140 fs/fhandle.c:94
+ ...
+
+Bytes 18-19 of 20 are uninitialized
+Memory access of size 20 starts at ffff888128a46380
+Data copied to user address 0000000020000240"
+
+Per Chuck Lever's suggestion, use kzalloc() instead of kmalloc() to
+solve the problem.
+
+Fixes: 990d6c2d7aee ("vfs: Add name to file handle conversion support")
+Suggested-by: Chuck Lever III <chuck.lever@oracle.com>
+Reported-and-tested-by: <syzbot+09b349b3066c2e0b1e96@syzkaller.appspotmail.com>
+Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+Link: https://lore.kernel.org/r/20240119153906.4367-1-n.zhandarovich@fintech.ru
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fhandle.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/fhandle.c b/fs/fhandle.c
+index f2bc27d1975e1..a8c25557c8c12 100644
+--- a/fs/fhandle.c
++++ b/fs/fhandle.c
+@@ -37,7 +37,7 @@ static long do_sys_name_to_handle(const struct path *path,
+ if (f_handle.handle_bytes > MAX_HANDLE_SZ)
+ return -EINVAL;
+
+- handle = kmalloc(sizeof(struct file_handle) + f_handle.handle_bytes,
++ handle = kzalloc(sizeof(struct file_handle) + f_handle.handle_bytes,
+ GFP_KERNEL);
+ if (!handle)
+ return -ENOMEM;
+--
+2.43.0
+
--- /dev/null
+From cf4d7b424a64c1fb7b9f877cbe17650adb63cee6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jan 2024 20:18:07 +0530
+Subject: drm/amd/display: Fix a potential buffer overflow in
+ 'dp_dsc_clock_en_read()'
+
+From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+
+[ Upstream commit 4b09715f1504f1b6e8dff0e9643630610bc05141 ]
+
+Tell snprintf() to store at most 10 bytes in the output buffer
+instead of 30.
+
+Fixes the below:
+drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_debugfs.c:1508 dp_dsc_clock_en_read() error: snprintf() is printing too much 30 vs 10
+
+Fixes: c06e09b76639 ("drm/amd/display: Add DSC parameters logging to debugfs")
+Cc: Alex Hung <alex.hung@amd.com>
+Cc: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Cc: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Cc: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Reviewed-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+index ee242d9d8b060..ff7dd17ad0763 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+@@ -1358,7 +1358,7 @@ static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf,
+ const uint32_t rd_buf_size = 10;
+ struct pipe_ctx *pipe_ctx;
+ ssize_t result = 0;
+- int i, r, str_len = 30;
++ int i, r, str_len = 10;
+
+ rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
+
+--
+2.43.0
+
--- /dev/null
+From 079f56548097bc881527674ea77e25c3f0ecfa4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Jan 2024 21:16:04 +0530
+Subject: drm/amd/display: Fix potential NULL pointer dereferences in
+ 'dcn10_set_output_transfer_func()'
+
+From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+
+[ Upstream commit 9ccfe80d022df7c595f1925afb31de2232900656 ]
+
+The 'stream' pointer is used in dcn10_set_output_transfer_func() before
+the check if 'stream' is NULL.
+
+Fixes the below:
+drivers/gpu/drm/amd/amdgpu/../display/dc/hwss/dcn10/dcn10_hwseq.c:1892 dcn10_set_output_transfer_func() warn: variable dereferenced before check 'stream' (see line 1875)
+
+Fixes: ddef02de0d71 ("drm/amd/display: add null checks before logging")
+Cc: Wyatt Wood <wyatt.wood@amd.com>
+Cc: Anthony Koo <Anthony.Koo@amd.com>
+Cc: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Cc: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Reviewed-by: Anthony Koo <Anthony.Koo@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/dcn10/dcn10_hw_sequencer.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+index 009b5861a3fec..d6c5d48c878ec 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+@@ -1854,6 +1854,9 @@ bool dcn10_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
+ {
+ struct dpp *dpp = pipe_ctx->plane_res.dpp;
+
++ if (!stream)
++ return false;
++
+ if (dpp == NULL)
+ return false;
+
+@@ -1876,8 +1879,8 @@ bool dcn10_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx,
+ } else
+ dpp->funcs->dpp_program_regamma_pwl(dpp, NULL, OPP_REGAMMA_BYPASS);
+
+- if (stream != NULL && stream->ctx != NULL &&
+- stream->out_transfer_func != NULL) {
++ if (stream->ctx &&
++ stream->out_transfer_func) {
+ log_tf(stream->ctx,
+ stream->out_transfer_func,
+ dpp->regamma_params.hw_points_num);
+--
+2.43.0
+
--- /dev/null
+From 3a416c89f179bce2d651c7080046e6a9159a5f1c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 Feb 2024 07:48:52 +0530
+Subject: drm/amdgpu: Fix missing break in ATOM_ARG_IMM Case of
+ atom_get_src_int()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+
+[ Upstream commit 7cf1ad2fe10634238b38442a851d89514cb14ea2 ]
+
+Missing break statement in the ATOM_ARG_IMM case of a switch statement,
+adds the missing break statement, ensuring that the program's control
+flow is as intended.
+
+Fixes the below:
+drivers/gpu/drm/amd/amdgpu/atom.c:323 atom_get_src_int() warn: ignoring unreachable code.
+
+Fixes: d38ceaf99ed0 ("drm/amdgpu: add core driver (v4)")
+Cc: Jammy Zhou <Jammy.Zhou@amd.com>
+Cc: Christian König <christian.koenig@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@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/atom.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
+index 1c5d9388ad0bb..cb6eb47aab65b 100644
+--- a/drivers/gpu/drm/amd/amdgpu/atom.c
++++ b/drivers/gpu/drm/amd/amdgpu/atom.c
+@@ -313,7 +313,7 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr,
+ DEBUG("IMM 0x%02X\n", val);
+ return val;
+ }
+- return 0;
++ break;
+ case ATOM_ARG_PLL:
+ idx = U8(*ptr);
+ (*ptr)++;
+--
+2.43.0
+
--- /dev/null
+From a808e6cddaeef4a9f97b10c82e32c00a3f46b7b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Nov 2023 11:36:20 -0500
+Subject: drm: Don't treat 0 as -1 in drm_fixp2int_ceil
+
+From: Harry Wentland <harry.wentland@amd.com>
+
+[ Upstream commit cf8837d7204481026335461629b84ac7f4538fa5 ]
+
+Unit testing this in VKMS shows that passing 0 into
+this function returns -1, which is highly counter-
+intuitive. Fix it by checking whether the input is
+>= 0 instead of > 0.
+
+Fixes: 64566b5e767f ("drm: Add drm_fixp_from_fraction and drm_fixp2int_ceil")
+Signed-off-by: Harry Wentland <harry.wentland@amd.com>
+Reviewed-by: Simon Ser <contact@emersion.fr>
+Reviewed-by: Melissa Wen <mwen@igalia.com>
+Signed-off-by: Melissa Wen <melissa.srw@gmail.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231108163647.106853-2-harry.wentland@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/drm/drm_fixed.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h
+index 03cb890690e83..6230088428cdb 100644
+--- a/include/drm/drm_fixed.h
++++ b/include/drm/drm_fixed.h
+@@ -94,7 +94,7 @@ static inline int drm_fixp2int_round(s64 a)
+
+ static inline int drm_fixp2int_ceil(s64 a)
+ {
+- if (a > 0)
++ if (a >= 0)
+ return drm_fixp2int(a + DRM_FIXED_ALMOST_ONE);
+ else
+ return drm_fixp2int(a - DRM_FIXED_ALMOST_ONE);
+--
+2.43.0
+
--- /dev/null
+From 657b5dbfaf4821ce6c862186f0112fb87f1efe34 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 15:13:28 +0800
+Subject: drm/lima: fix a memleak in lima_heap_alloc
+
+From: Zhipeng Lu <alexious@zju.edu.cn>
+
+[ Upstream commit 04ae3eb470e52a3c41babe85ff8cee195e4dcbea ]
+
+When lima_vm_map_bo fails, the resources need to be deallocated, or
+there will be memleaks.
+
+Fixes: 6aebc51d7aef ("drm/lima: support heap buffer creation")
+Signed-off-by: Zhipeng Lu <alexious@zju.edu.cn>
+Signed-off-by: Qiang Yu <yuq825@gmail.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240117071328.3811480-1-alexious@zju.edu.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/lima/lima_gem.c | 23 ++++++++++++++---------
+ 1 file changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
+index 0f1ca0b0db495..d72c5bf4e5ac1 100644
+--- a/drivers/gpu/drm/lima/lima_gem.c
++++ b/drivers/gpu/drm/lima/lima_gem.c
+@@ -75,29 +75,34 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm)
+ } else {
+ bo->base.sgt = kmalloc(sizeof(*bo->base.sgt), GFP_KERNEL);
+ if (!bo->base.sgt) {
+- sg_free_table(&sgt);
+- return -ENOMEM;
++ ret = -ENOMEM;
++ goto err_out0;
+ }
+ }
+
+ ret = dma_map_sgtable(dev, &sgt, DMA_BIDIRECTIONAL, 0);
+- if (ret) {
+- sg_free_table(&sgt);
+- kfree(bo->base.sgt);
+- bo->base.sgt = NULL;
+- return ret;
+- }
++ if (ret)
++ goto err_out1;
+
+ *bo->base.sgt = sgt;
+
+ if (vm) {
+ ret = lima_vm_map_bo(vm, bo, old_size >> PAGE_SHIFT);
+ if (ret)
+- return ret;
++ goto err_out2;
+ }
+
+ bo->heap_size = new_size;
+ return 0;
++
++err_out2:
++ dma_unmap_sgtable(dev, &sgt, DMA_BIDIRECTIONAL, 0);
++err_out1:
++ kfree(bo->base.sgt);
++ bo->base.sgt = NULL;
++err_out0:
++ sg_free_table(&sgt);
++ return ret;
+ }
+
+ int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file,
+--
+2.43.0
+
--- /dev/null
+From adddf8366f39e18c26b7532cd8187a94bbad5efb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Feb 2024 09:53:09 +0100
+Subject: drm/mediatek: dsi: Fix DSI RGB666 formats and definitions
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit fae6f815505301b92d9113764f4d76d0bfe45607 ]
+
+The register bits definitions for RGB666 formats are wrong in multiple
+ways: first, in the DSI_PS_SEL bits region, the Packed 18-bits RGB666
+format is selected with bit 1, while the Loosely Packed one is bit 2,
+and second - the definition name "LOOSELY_PS_18BIT_RGB666" is wrong
+because the loosely packed format is 24 bits instead!
+
+Either way, functions mtk_dsi_ps_control_vact() and mtk_dsi_ps_control()
+do not even agree on the DSI_PS_SEL bit to set in DSI_PSCTRL: one sets
+loosely packed (24) on RGB666, the other sets packed (18), and the other
+way around for RGB666_PACKED.
+
+Fixing this entire stack of issues is done in one go:
+ - Use the correct bit for the Loosely Packed RGB666 definition
+ - Rename LOOSELY_PS_18BIT_RGB666 to LOOSELY_PS_24BIT_RGB666
+ - Change ps_bpp_mode in mtk_dsi_ps_control_vact() to set:
+ - Loosely Packed, 24-bits for MIPI_DSI_FMT_RGB666
+ - Packed, 18-bits for MIPI_DSI_FMT_RGB666_PACKED
+
+Fixes: 2e54c14e310f ("drm/mediatek: Add DSI sub driver")
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20240215085316.56835-3-angelogioacchino.delregno@collabora.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_dsi.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
+index 3e74c7c1b89fa..d871b1dba083d 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
++++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
+@@ -70,8 +70,8 @@
+ #define DSI_PS_WC 0x3fff
+ #define DSI_PS_SEL (3 << 16)
+ #define PACKED_PS_16BIT_RGB565 (0 << 16)
+-#define LOOSELY_PS_18BIT_RGB666 (1 << 16)
+-#define PACKED_PS_18BIT_RGB666 (2 << 16)
++#define PACKED_PS_18BIT_RGB666 (1 << 16)
++#define LOOSELY_PS_24BIT_RGB666 (2 << 16)
+ #define PACKED_PS_24BIT_RGB888 (3 << 16)
+
+ #define DSI_VSA_NL 0x20
+@@ -366,10 +366,10 @@ static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
+ ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
+ break;
+ case MIPI_DSI_FMT_RGB666:
+- ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
++ ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
+ break;
+ case MIPI_DSI_FMT_RGB666_PACKED:
+- ps_bpp_mode |= LOOSELY_PS_18BIT_RGB666;
++ ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
+ break;
+ case MIPI_DSI_FMT_RGB565:
+ ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
+@@ -423,7 +423,7 @@ static void mtk_dsi_ps_control(struct mtk_dsi *dsi)
+ dsi_tmp_buf_bpp = 3;
+ break;
+ case MIPI_DSI_FMT_RGB666:
+- tmp_reg = LOOSELY_PS_18BIT_RGB666;
++ tmp_reg = LOOSELY_PS_24BIT_RGB666;
+ dsi_tmp_buf_bpp = 3;
+ break;
+ case MIPI_DSI_FMT_RGB666_PACKED:
+--
+2.43.0
+
--- /dev/null
+From 298efcc344a0f01d1bed0d8a856acd953730833e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Feb 2024 13:23:29 -0800
+Subject: drm/mediatek: Fix a null pointer crash in
+ mtk_drm_crtc_finish_page_flip
+
+From: Hsin-Yi Wang <hsinyi@chromium.org>
+
+[ Upstream commit c958e86e9cc1b48cac004a6e245154dfba8e163b ]
+
+It's possible that mtk_crtc->event is NULL in
+mtk_drm_crtc_finish_page_flip().
+
+pending_needs_vblank value is set by mtk_crtc->event, but in
+mtk_drm_crtc_atomic_flush(), it's is not guarded by the same
+lock in mtk_drm_finish_page_flip(), thus a race condition happens.
+
+Consider the following case:
+
+CPU1 CPU2
+step 1:
+mtk_drm_crtc_atomic_begin()
+mtk_crtc->event is not null,
+ step 1:
+ mtk_drm_crtc_atomic_flush:
+ mtk_drm_crtc_update_config(
+ !!mtk_crtc->event)
+step 2:
+mtk_crtc_ddp_irq ->
+mtk_drm_finish_page_flip:
+lock
+mtk_crtc->event set to null,
+pending_needs_vblank set to false
+unlock
+ pending_needs_vblank set to true,
+
+ step 2:
+ mtk_crtc_ddp_irq ->
+ mtk_drm_finish_page_flip called again,
+ pending_needs_vblank is still true
+ //null pointer
+
+Instead of guarding the entire mtk_drm_crtc_atomic_flush(), it's more
+efficient to just check if mtk_crtc->event is null before use.
+
+Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.")
+Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20240223212404.3709690-1-hsinyi@chromium.org/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+index 558000db4a100..beaaf44004cfd 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+@@ -91,11 +91,13 @@ static void mtk_drm_crtc_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
+ struct drm_crtc *crtc = &mtk_crtc->base;
+ unsigned long flags;
+
+- spin_lock_irqsave(&crtc->dev->event_lock, flags);
+- drm_crtc_send_vblank_event(crtc, mtk_crtc->event);
+- drm_crtc_vblank_put(crtc);
+- mtk_crtc->event = NULL;
+- spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
++ if (mtk_crtc->event) {
++ spin_lock_irqsave(&crtc->dev->event_lock, flags);
++ drm_crtc_send_vblank_event(crtc, mtk_crtc->event);
++ drm_crtc_vblank_put(crtc);
++ mtk_crtc->event = NULL;
++ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
++ }
+ }
+
+ static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
+--
+2.43.0
+
--- /dev/null
+From 1e54af0c5810386d3c84c237bafe29f87b692a74 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Feb 2024 11:39:47 -0800
+Subject: drm/msm/dpu: add division of drm_display_mode's hskew parameter
+
+From: Paloma Arellano <quic_parellan@quicinc.com>
+
+[ Upstream commit 551ee0f210991d25f336bc27262353bfe99d3eed ]
+
+Setting up the timing engine when the physical encoder has a split role
+neglects dividing the drm_display_mode's hskew parameter. Let's fix this
+since this must also be done in preparation for implementing YUV420 over
+DP.
+
+Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support")
+Signed-off-by: Paloma Arellano <quic_parellan@quicinc.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/579605/
+Link: https://lore.kernel.org/r/20240222194025.25329-3-quic_parellan@quicinc.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+index 09aeec00bf5e2..2baade1cd4876 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+@@ -257,12 +257,14 @@ static void dpu_encoder_phys_vid_setup_timing_engine(
+ mode.htotal >>= 1;
+ mode.hsync_start >>= 1;
+ mode.hsync_end >>= 1;
++ mode.hskew >>= 1;
+
+ DPU_DEBUG_VIDENC(phys_enc,
+- "split_role %d, halve horizontal %d %d %d %d\n",
++ "split_role %d, halve horizontal %d %d %d %d %d\n",
+ phys_enc->split_role,
+ mode.hdisplay, mode.htotal,
+- mode.hsync_start, mode.hsync_end);
++ mode.hsync_start, mode.hsync_end,
++ mode.hskew);
+ }
+
+ drm_mode_to_intf_timing_params(phys_enc, &mode, &timing_params);
+--
+2.43.0
+
--- /dev/null
+From 27a027bf819c3c87cf44ea068b16890a8b464ec4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jan 2024 16:47:36 -0800
+Subject: drm/msm/dpu: fix the programming of INTF_CFG2_DATA_HCTL_EN
+
+From: Abhinav Kumar <quic_abhinavk@quicinc.com>
+
+[ Upstream commit 2f4a67a3894e15c135125cb54edc5b43abc1b70e ]
+
+Currently INTF_CFG2_DATA_HCTL_EN is coupled with the enablement
+of widebus but this is incorrect because we should be enabling
+this bit independent of widebus except for cases where compression
+is enabled in one pixel per clock mode.
+
+Fix this by making the condition checks more explicit and enabling
+INTF_CFG2_DATA_HCTL_EN for all other cases when supported by DPU.
+
+Fixes: 3309a7563971 ("drm/msm/dpu: revise timing engine programming to support widebus feature")
+Suggested-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/576722/
+Link: https://lore.kernel.org/r/20240201004737.2478-1-quic_abhinavk@quicinc.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 7 +++++++
+ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 7 +++++++
+ .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 1 +
+ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 15 +++++++++------
+ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 1 +
+ 5 files changed, 25 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+index 25245ef386db6..4bdde5cb23aae 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+@@ -228,6 +228,13 @@ bool dpu_encoder_is_widebus_enabled(const struct drm_encoder *drm_enc)
+ return dpu_enc->wide_bus_en;
+ }
+
++bool dpu_encoder_is_dsc_enabled(const struct drm_encoder *drm_enc)
++{
++ const struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
++
++ return dpu_enc->dsc ? true : false;
++}
++
+ int dpu_encoder_get_crc_values_cnt(const struct drm_encoder *drm_enc)
+ {
+ struct dpu_encoder_virt *dpu_enc;
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+index 9e7236ef34e6d..a71efa2b9e508 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+@@ -175,6 +175,13 @@ int dpu_encoder_get_vsync_count(struct drm_encoder *drm_enc);
+
+ bool dpu_encoder_is_widebus_enabled(const struct drm_encoder *drm_enc);
+
++/**
++ * dpu_encoder_is_dsc_enabled - indicate whether dsc is enabled
++ * for the encoder.
++ * @drm_enc: Pointer to previously created drm encoder structure
++ */
++bool dpu_encoder_is_dsc_enabled(const struct drm_encoder *drm_enc);
++
+ /**
+ * dpu_encoder_get_crc_values_cnt - get number of physical encoders contained
+ * in virtual encoder that can collect CRC values
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+index 2c14646661b77..09aeec00bf5e2 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+@@ -100,6 +100,7 @@ static void drm_mode_to_intf_timing_params(
+ }
+
+ timing->wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent);
++ timing->compression_en = dpu_encoder_is_dsc_enabled(phys_enc->parent);
+
+ /*
+ * for DP, divide the horizonal parameters by 2 when
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+index 384558d2f9602..1debac4fcc3eb 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+@@ -154,13 +154,8 @@ static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx,
+ hsync_ctl = (hsync_period << 16) | p->hsync_pulse_width;
+ display_hctl = (hsync_end_x << 16) | hsync_start_x;
+
+- /*
+- * DATA_HCTL_EN controls data timing which can be different from
+- * video timing. It is recommended to enable it for all cases, except
+- * if compression is enabled in 1 pixel per clock mode
+- */
+ if (p->wide_bus_en)
+- intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN | INTF_CFG2_DATA_HCTL_EN;
++ intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN;
+
+ data_width = p->width;
+
+@@ -230,6 +225,14 @@ static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx,
+ DPU_REG_WRITE(c, INTF_CONFIG, intf_cfg);
+ DPU_REG_WRITE(c, INTF_PANEL_FORMAT, panel_format);
+ if (ctx->cap->features & BIT(DPU_DATA_HCTL_EN)) {
++ /*
++ * DATA_HCTL_EN controls data timing which can be different from
++ * video timing. It is recommended to enable it for all cases, except
++ * if compression is enabled in 1 pixel per clock mode
++ */
++ if (!(p->compression_en && !p->wide_bus_en))
++ intf_cfg2 |= INTF_CFG2_DATA_HCTL_EN;
++
+ DPU_REG_WRITE(c, INTF_CONFIG2, intf_cfg2);
+ DPU_REG_WRITE(c, INTF_DISPLAY_DATA_HCTL, display_data_hctl);
+ DPU_REG_WRITE(c, INTF_ACTIVE_DATA_HCTL, active_data_hctl);
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
+index e75339b96a1d2..7f502c8bee1d4 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
+@@ -33,6 +33,7 @@ struct intf_timing_params {
+ u32 hsync_skew;
+
+ bool wide_bus_en;
++ bool compression_en;
+ };
+
+ struct intf_prog_fetch {
+--
+2.43.0
+
--- /dev/null
+From de3e5e4916d71cd2737532f1b159ae4e03850753 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 Feb 2024 18:45:27 +0100
+Subject: drm/msm/dpu: Only enable DSC_MODE_MULTIPLEX if dsc_merge is enabled
+
+From: Marijn Suijten <marijn.suijten@somainline.org>
+
+[ Upstream commit 06267d22f9ee6fd34150b6dcdb2fa6983e1a85bc ]
+
+When the topology calls for two interfaces on the current fixed topology
+of 2 DSC blocks, or uses 1 DSC block for a single interface (e.g. SC7280
+with only one DSC block), there should be no merging of DSC output.
+
+This is already represented by the return value of
+dpu_encoder_use_dsc_merge(), but not yet used to correctly configure
+this flag.
+
+Fixes: 58dca9810749 ("drm/msm/disp/dpu1: Add support for DSC in encoder")
+Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/577067/
+Link: https://lore.kernel.org/r/20240204-dpu-dsc-multiplex-v1-1-080963233c52@somainline.org
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+index 4bdde5cb23aae..3632f0768aa9e 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+@@ -1871,7 +1871,9 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
+ dsc_common_mode = 0;
+ pic_width = dsc->pic_width;
+
+- dsc_common_mode = DSC_MODE_MULTIPLEX | DSC_MODE_SPLIT_PANEL;
++ dsc_common_mode = DSC_MODE_SPLIT_PANEL;
++ if (dpu_encoder_use_dsc_merge(enc_master->parent))
++ dsc_common_mode |= DSC_MODE_MULTIPLEX;
+ if (enc_master->intf_mode == INTF_MODE_VIDEO)
+ dsc_common_mode |= DSC_MODE_VIDEO;
+
+--
+2.43.0
+
--- /dev/null
+From a595b1b10d14ad80f506ebe9b3add8002840b385 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Dec 2023 14:13:11 -0800
+Subject: drm/panel-edp: use put_sync in unprepare
+
+From: Hsin-Yi Wang <hsinyi@chromium.org>
+
+[ Upstream commit 49ddab089611ae5ddd0201ddbbf633da75bfcc25 ]
+
+Some edp panel requires T10 (Delay from end of valid video data transmitted
+by the Source device to power-off) less than 500ms. Using autosuspend with
+delay set as 1000 violates this requirement.
+
+Use put_sync_suspend in unprepare to meet the spec. For other cases (such
+as getting EDID), it still uses autosuspend.
+
+Suggested-by: Douglas Anderson <dianders@chromium.org>
+Fixes: 3235b0f20a0a ("drm/panel: panel-simple: Use runtime pm to avoid excessive unprepare / prepare")
+Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231220221418.2610185-1-hsinyi@chromium.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/panel/panel-edp.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c
+index 42584d8a9aeb6..bfcddd4aa9322 100644
+--- a/drivers/gpu/drm/panel/panel-edp.c
++++ b/drivers/gpu/drm/panel/panel-edp.c
+@@ -413,8 +413,7 @@ static int panel_edp_unprepare(struct drm_panel *panel)
+ if (!p->prepared)
+ return 0;
+
+- pm_runtime_mark_last_busy(panel->dev);
+- ret = pm_runtime_put_autosuspend(panel->dev);
++ ret = pm_runtime_put_sync_suspend(panel->dev);
+ if (ret < 0)
+ return ret;
+ p->prepared = false;
+--
+2.43.0
+
--- /dev/null
+From af8e7d3ee2eb69f859d28c4f585cb7241d4c1ea9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Feb 2024 08:48:14 -0800
+Subject: drm/radeon/ni: Fix wrong firmware size logging in ni_init_microcode()
+
+From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+
+[ Upstream commit c4891d979c7668b195a0a75787967ec95a24ecef ]
+
+Clean up a typo in pr_err() erroneously printing NI MC 'rdev->mc_fw->size'
+during SMC firmware load. Log 'rdev->smc_fw->size' instead.
+
+Found by Linux Verification Center (linuxtesting.org) with static
+analysis tool SVACE.
+
+Fixes: 6596afd48af4 ("drm/radeon/kms: add dpm support for btc (v3)")
+Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/ni.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
+index 927e5f42e97d0..3e48cbb522a1c 100644
+--- a/drivers/gpu/drm/radeon/ni.c
++++ b/drivers/gpu/drm/radeon/ni.c
+@@ -813,7 +813,7 @@ int ni_init_microcode(struct radeon_device *rdev)
+ err = 0;
+ } else if (rdev->smc_fw->size != smc_req_size) {
+ pr_err("ni_mc: Bogus length %zu in firmware \"%s\"\n",
+- rdev->mc_fw->size, fw_name);
++ rdev->smc_fw->size, fw_name);
+ err = -EINVAL;
+ }
+ }
+--
+2.43.0
+
--- /dev/null
+From 277814e0a00b575c09c32448e8a4df8327bb8a06 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Dec 2023 18:41:54 +0100
+Subject: drm/rockchip: inno_hdmi: Fix video timing
+
+From: Alex Bee <knaerzche@gmail.com>
+
+[ Upstream commit 47a145c03484d33e65d773169d5ca1b9fe2a492e ]
+
+The controller wants the difference between *total and *sync_start in the
+HDMI_VIDEO_EXT_*DELAY registers. Otherwise the signal is very unstable for
+certain non-VIC modes. See downstream commit [0].
+
+[0] https://github.com/rockchip-linux/kernel/commit/8eb559f2502c
+
+Fixes: 412d4ae6b7a5 ("drm/rockchip: hdmi: add Innosilicon HDMI support")
+Co-developed-by: Zheng Yang <zhengyang@rock-chips.com>
+Signed-off-by: Zheng Yang <zhengyang@rock-chips.com>
+Signed-off-by: Alex Bee <knaerzche@gmail.com>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231222174220.55249-4-knaerzche@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/inno_hdmi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
+index f51774866f412..8f230f4c01bc3 100644
+--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
++++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
+@@ -411,7 +411,7 @@ static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
+ hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_L, value & 0xFF);
+ hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF);
+
+- value = mode->hsync_start - mode->hdisplay;
++ value = mode->htotal - mode->hsync_start;
+ hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_L, value & 0xFF);
+ hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF);
+
+@@ -426,7 +426,7 @@ static int inno_hdmi_config_video_timing(struct inno_hdmi *hdmi,
+ value = mode->vtotal - mode->vdisplay;
+ hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VBLANK, value & 0xFF);
+
+- value = mode->vsync_start - mode->vdisplay;
++ value = mode->vtotal - mode->vsync_start;
+ hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDELAY, value & 0xFF);
+
+ value = mode->vsync_end - mode->vsync_start;
+--
+2.43.0
+
--- /dev/null
+From c46626d8533aa5ec49cc9ec4a0c57655c232a481 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Nov 2023 13:29:48 +0100
+Subject: drm/rockchip: lvds: do not overwrite error code
+
+From: Quentin Schulz <quentin.schulz@theobroma-systems.com>
+
+[ Upstream commit 79b09453c4e369ca81cfb670d0136d089e3b92f0 ]
+
+ret variable stores the return value of drm_of_find_panel_or_bridge
+which can return error codes different from EPROBE_DEFER. Therefore,
+let's just return that error code instead of forcing it to EPROBE_DEFER.
+
+Fixes: 34cc0aa25456 ("drm/rockchip: Add support for Rockchip Soc LVDS")
+Cc: Quentin Schulz <foss+kernel@0leil.net>
+Signed-off-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231120-rk-lvds-defer-msg-v2-1-9c59a5779cf9@theobroma-systems.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/rockchip_lvds.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c
+index 68f6ebb33460b..1fde888cdd827 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_lvds.c
++++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c
+@@ -578,7 +578,6 @@ static int rockchip_lvds_bind(struct device *dev, struct device *master,
+ goto err_put_port;
+ } else if (ret) {
+ DRM_DEV_ERROR(dev, "failed to find panel and bridge node\n");
+- ret = -EPROBE_DEFER;
+ goto err_put_port;
+ }
+ if (lvds->panel)
+--
+2.43.0
+
--- /dev/null
+From 6d5e178f72e8926c750667c0addc9a0067017eee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Nov 2023 13:29:49 +0100
+Subject: drm/rockchip: lvds: do not print scary message when probing defer
+
+From: Quentin Schulz <quentin.schulz@theobroma-systems.com>
+
+[ Upstream commit 52d11c863ac92e36a0365249f7f6d27ac48c78bc ]
+
+This scary message can misled the user into thinking something bad has
+happened and needs to be fixed, however it could simply be part of a
+normal boot process where EPROBE_DEFER is taken into account. Therefore,
+let's use dev_err_probe so that this message doesn't get shown (by
+default) when the return code is EPROBE_DEFER.
+
+Fixes: 34cc0aa25456 ("drm/rockchip: Add support for Rockchip Soc LVDS")
+Cc: Quentin Schulz <foss+kernel@0leil.net>
+Signed-off-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231120-rk-lvds-defer-msg-v2-2-9c59a5779cf9@theobroma-systems.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/rockchip_lvds.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c
+index 1fde888cdd827..eb4a108c5bd2a 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_lvds.c
++++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c
+@@ -577,7 +577,7 @@ static int rockchip_lvds_bind(struct device *dev, struct device *master,
+ ret = -EINVAL;
+ goto err_put_port;
+ } else if (ret) {
+- DRM_DEV_ERROR(dev, "failed to find panel and bridge node\n");
++ dev_err_probe(dev, ret, "failed to find panel and bridge node\n");
+ goto err_put_port;
+ }
+ if (lvds->panel)
+--
+2.43.0
+
--- /dev/null
+From 50ef85a16b01bf6f39e3e7edc3e5f3bd063c2dc0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Oct 2023 22:10:55 +0800
+Subject: drm/tegra: dpaux: Fix PM disable depth imbalance in tegra_dpaux_probe
+
+From: Zhang Shurong <zhang_shurong@foxmail.com>
+
+[ Upstream commit 0800880f4eb789b7d299db40f2e86e056bd33a4e ]
+
+The pm_runtime_enable function increases the power disable depth,
+which means that we must perform a matching decrement on the error
+handling path to maintain balance within the given context.
+Additionally, we need to address the same issue for pm_runtime_get_sync.
+We fix this by invoking pm_runtime_disable and pm_runtime_put_sync
+when error returns.
+
+Fixes: 82b81b3ec1a7 ("drm/tegra: dpaux: Implement runtime PM")
+Signed-off-by: Zhang Shurong <zhang_shurong@foxmail.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/tencent_B13DB7F6C0023C46157250A524966F326A09@qq.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tegra/dpaux.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
+index d773ef4854188..b563988fb6848 100644
+--- a/drivers/gpu/drm/tegra/dpaux.c
++++ b/drivers/gpu/drm/tegra/dpaux.c
+@@ -524,7 +524,7 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
+ if (err < 0) {
+ dev_err(dpaux->dev, "failed to request IRQ#%u: %d\n",
+ dpaux->irq, err);
+- return err;
++ goto err_pm_disable;
+ }
+
+ disable_irq(dpaux->irq);
+@@ -544,7 +544,7 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
+ */
+ err = tegra_dpaux_pad_config(dpaux, DPAUX_PADCTL_FUNC_I2C);
+ if (err < 0)
+- return err;
++ goto err_pm_disable;
+
+ #ifdef CONFIG_GENERIC_PINCONF
+ dpaux->desc.name = dev_name(&pdev->dev);
+@@ -557,7 +557,8 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
+ dpaux->pinctrl = devm_pinctrl_register(&pdev->dev, &dpaux->desc, dpaux);
+ if (IS_ERR(dpaux->pinctrl)) {
+ dev_err(&pdev->dev, "failed to register pincontrol\n");
+- return PTR_ERR(dpaux->pinctrl);
++ err = PTR_ERR(dpaux->pinctrl);
++ goto err_pm_disable;
+ }
+ #endif
+ /* enable and clear all interrupts */
+@@ -573,10 +574,15 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
+ err = devm_of_dp_aux_populate_ep_devices(&dpaux->aux);
+ if (err < 0) {
+ dev_err(dpaux->dev, "failed to populate AUX bus: %d\n", err);
+- return err;
++ goto err_pm_disable;
+ }
+
+ return 0;
++
++err_pm_disable:
++ pm_runtime_put_sync(&pdev->dev);
++ pm_runtime_disable(&pdev->dev);
++ return err;
+ }
+
+ static int tegra_dpaux_remove(struct platform_device *pdev)
+--
+2.43.0
+
--- /dev/null
+From 97988c5a9c71d0843d65256c1382a1720a95003c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Oct 2023 08:07:38 +0000
+Subject: drm/tegra: dsi: Add missing check for of_find_device_by_node
+
+From: Chen Ni <nichen@iscas.ac.cn>
+
+[ Upstream commit afe6fcb9775882230cd29b529203eabd5d2a638d ]
+
+Add check for the return value of of_find_device_by_node() and return
+the error if it fails in order to avoid NULL pointer dereference.
+
+Fixes: e94236cde4d5 ("drm/tegra: dsi: Add ganged mode support")
+Signed-off-by: Chen Ni <nichen@iscas.ac.cn>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231024080738.825553-1-nichen@iscas.ac.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tegra/dsi.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
+index de1333dc0d867..0adce882f157b 100644
+--- a/drivers/gpu/drm/tegra/dsi.c
++++ b/drivers/gpu/drm/tegra/dsi.c
+@@ -1534,9 +1534,11 @@ static int tegra_dsi_ganged_probe(struct tegra_dsi *dsi)
+ np = of_parse_phandle(dsi->dev->of_node, "nvidia,ganged-mode", 0);
+ if (np) {
+ struct platform_device *gangster = of_find_device_by_node(np);
++ of_node_put(np);
++ if (!gangster)
++ return -EPROBE_DEFER;
+
+ dsi->slave = platform_get_drvdata(gangster);
+- of_node_put(np);
+
+ if (!dsi->slave) {
+ put_device(&gangster->dev);
+--
+2.43.0
+
--- /dev/null
+From 7d6b62d5a0e593c6a7481cfbdb2021948649b63d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Sep 2023 17:22:09 +0200
+Subject: drm/tegra: dsi: Fix missing pm_runtime_disable() in the error
+ handling path of tegra_dsi_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 5286a9fc280c45b6b307ee1b07f7a997e042252c ]
+
+If an error occurs after calling pm_runtime_enable(), pm_runtime_disable()
+should be called as already done in the remove function.
+
+Fixes: ef8187d75265 ("drm/tegra: dsi: Implement runtime PM")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/ee4a15c9cd4b574a55cd67c30d2411239ba2cee9.1693667005.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tegra/dsi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
+index 815e32e05f600..7bb26655cb3cc 100644
+--- a/drivers/gpu/drm/tegra/dsi.c
++++ b/drivers/gpu/drm/tegra/dsi.c
+@@ -1665,6 +1665,7 @@ static int tegra_dsi_probe(struct platform_device *pdev)
+ return 0;
+
+ unregister:
++ pm_runtime_disable(&pdev->dev);
+ mipi_dsi_host_unregister(&dsi->host);
+ mipi_free:
+ tegra_mipi_free(dsi->mipi);
+--
+2.43.0
+
--- /dev/null
+From 0daa0ac275cbb664d78a4ac206b1066bb09eada9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Sep 2023 17:22:08 +0200
+Subject: drm/tegra: dsi: Fix some error handling paths in tegra_dsi_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 830c1ded356369cd1303e8bb87ce3fea6e744de8 ]
+
+If an error occurs after calling tegra_output_probe(),
+tegra_output_remove() should be called as already done in the remove
+function.
+
+Fixes: dec727399a4b ("drm/tegra: Add DSI support")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/16820073278d031f6c474a08d5f22a255158585e.1693667005.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tegra/dsi.c | 54 ++++++++++++++++++++++++-------------
+ 1 file changed, 35 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
+index 6cbba2adb6e5a..815e32e05f600 100644
+--- a/drivers/gpu/drm/tegra/dsi.c
++++ b/drivers/gpu/drm/tegra/dsi.c
+@@ -1586,44 +1586,58 @@ static int tegra_dsi_probe(struct platform_device *pdev)
+
+ if (!pdev->dev.pm_domain) {
+ dsi->rst = devm_reset_control_get(&pdev->dev, "dsi");
+- if (IS_ERR(dsi->rst))
+- return PTR_ERR(dsi->rst);
++ if (IS_ERR(dsi->rst)) {
++ err = PTR_ERR(dsi->rst);
++ goto remove;
++ }
+ }
+
+ dsi->clk = devm_clk_get(&pdev->dev, NULL);
+- if (IS_ERR(dsi->clk))
+- return dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk),
+- "cannot get DSI clock\n");
++ if (IS_ERR(dsi->clk)) {
++ err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk),
++ "cannot get DSI clock\n");
++ goto remove;
++ }
+
+ dsi->clk_lp = devm_clk_get(&pdev->dev, "lp");
+- if (IS_ERR(dsi->clk_lp))
+- return dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_lp),
+- "cannot get low-power clock\n");
++ if (IS_ERR(dsi->clk_lp)) {
++ err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_lp),
++ "cannot get low-power clock\n");
++ goto remove;
++ }
+
+ dsi->clk_parent = devm_clk_get(&pdev->dev, "parent");
+- if (IS_ERR(dsi->clk_parent))
+- return dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_parent),
+- "cannot get parent clock\n");
++ if (IS_ERR(dsi->clk_parent)) {
++ err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_parent),
++ "cannot get parent clock\n");
++ goto remove;
++ }
+
+ dsi->vdd = devm_regulator_get(&pdev->dev, "avdd-dsi-csi");
+- if (IS_ERR(dsi->vdd))
+- return dev_err_probe(&pdev->dev, PTR_ERR(dsi->vdd),
+- "cannot get VDD supply\n");
++ if (IS_ERR(dsi->vdd)) {
++ err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->vdd),
++ "cannot get VDD supply\n");
++ goto remove;
++ }
+
+ err = tegra_dsi_setup_clocks(dsi);
+ if (err < 0) {
+ dev_err(&pdev->dev, "cannot setup clocks\n");
+- return err;
++ goto remove;
+ }
+
+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ dsi->regs = devm_ioremap_resource(&pdev->dev, regs);
+- if (IS_ERR(dsi->regs))
+- return PTR_ERR(dsi->regs);
++ if (IS_ERR(dsi->regs)) {
++ err = PTR_ERR(dsi->regs);
++ goto remove;
++ }
+
+ dsi->mipi = tegra_mipi_request(&pdev->dev, pdev->dev.of_node);
+- if (IS_ERR(dsi->mipi))
+- return PTR_ERR(dsi->mipi);
++ if (IS_ERR(dsi->mipi)) {
++ err = PTR_ERR(dsi->mipi);
++ goto remove;
++ }
+
+ dsi->host.ops = &tegra_dsi_host_ops;
+ dsi->host.dev = &pdev->dev;
+@@ -1654,6 +1668,8 @@ static int tegra_dsi_probe(struct platform_device *pdev)
+ mipi_dsi_host_unregister(&dsi->host);
+ mipi_free:
+ tegra_mipi_free(dsi->mipi);
++remove:
++ tegra_output_remove(&dsi->output);
+ return err;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 0d2a5d1bc710b559f0240558f9fdbae74d2b493c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Sep 2021 18:56:40 +0800
+Subject: drm/tegra: dsi: Make use of the helper function dev_err_probe()
+
+From: Cai Huoqing <caihuoqing@baidu.com>
+
+[ Upstream commit fc75e4fcbd1e4252a0481ebb23cd4516c127a8e2 ]
+
+When possible use dev_err_probe help to properly deal with the
+PROBE_DEFER error, the benefit is that DEFER issue will be logged
+in the devices_deferred debugfs file.
+And using dev_err_probe() can reduce code size, the error value
+gets printed.
+
+Signed-off-by: Cai Huoqing <caihuoqing@baidu.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Stable-dep-of: 830c1ded3563 ("drm/tegra: dsi: Fix some error handling paths in tegra_dsi_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tegra/dsi.c | 28 ++++++++++++----------------
+ 1 file changed, 12 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
+index 0adce882f157b..6cbba2adb6e5a 100644
+--- a/drivers/gpu/drm/tegra/dsi.c
++++ b/drivers/gpu/drm/tegra/dsi.c
+@@ -1591,28 +1591,24 @@ static int tegra_dsi_probe(struct platform_device *pdev)
+ }
+
+ dsi->clk = devm_clk_get(&pdev->dev, NULL);
+- if (IS_ERR(dsi->clk)) {
+- dev_err(&pdev->dev, "cannot get DSI clock\n");
+- return PTR_ERR(dsi->clk);
+- }
++ if (IS_ERR(dsi->clk))
++ return dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk),
++ "cannot get DSI clock\n");
+
+ dsi->clk_lp = devm_clk_get(&pdev->dev, "lp");
+- if (IS_ERR(dsi->clk_lp)) {
+- dev_err(&pdev->dev, "cannot get low-power clock\n");
+- return PTR_ERR(dsi->clk_lp);
+- }
++ if (IS_ERR(dsi->clk_lp))
++ return dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_lp),
++ "cannot get low-power clock\n");
+
+ dsi->clk_parent = devm_clk_get(&pdev->dev, "parent");
+- if (IS_ERR(dsi->clk_parent)) {
+- dev_err(&pdev->dev, "cannot get parent clock\n");
+- return PTR_ERR(dsi->clk_parent);
+- }
++ if (IS_ERR(dsi->clk_parent))
++ return dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_parent),
++ "cannot get parent clock\n");
+
+ dsi->vdd = devm_regulator_get(&pdev->dev, "avdd-dsi-csi");
+- if (IS_ERR(dsi->vdd)) {
+- dev_err(&pdev->dev, "cannot get VDD supply\n");
+- return PTR_ERR(dsi->vdd);
+- }
++ if (IS_ERR(dsi->vdd))
++ return dev_err_probe(&pdev->dev, PTR_ERR(dsi->vdd),
++ "cannot get VDD supply\n");
+
+ err = tegra_dsi_setup_clocks(dsi);
+ if (err < 0) {
+--
+2.43.0
+
--- /dev/null
+From 2b2130cea539011b126456a7b2b2d6e04eab3ebf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Jul 2023 11:23:41 +0800
+Subject: drm/tegra: hdmi: Convert to devm_platform_ioremap_resource()
+
+From: Yangtao Li <frank.li@vivo.com>
+
+[ Upstream commit faae5646c13f4697fd2ba29b10e38f9be5aa890a ]
+
+Use devm_platform_ioremap_resource() to simplify code.
+
+Signed-off-by: Yangtao Li <frank.li@vivo.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230710032355.72914-5-frank.li@vivo.com
+Stable-dep-of: 643ae131b859 ("drm/tegra: hdmi: Fix some error handling paths in tegra_hdmi_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tegra/hdmi.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
+index bf240767dad9f..f83d9041327f0 100644
+--- a/drivers/gpu/drm/tegra/hdmi.c
++++ b/drivers/gpu/drm/tegra/hdmi.c
+@@ -1776,7 +1776,6 @@ static irqreturn_t tegra_hdmi_irq(int irq, void *data)
+ static int tegra_hdmi_probe(struct platform_device *pdev)
+ {
+ struct tegra_hdmi *hdmi;
+- struct resource *regs;
+ int err;
+
+ hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
+@@ -1838,8 +1837,7 @@ static int tegra_hdmi_probe(struct platform_device *pdev)
+ if (err < 0)
+ return err;
+
+- regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- hdmi->regs = devm_ioremap_resource(&pdev->dev, regs);
++ hdmi->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(hdmi->regs))
+ return PTR_ERR(hdmi->regs);
+
+--
+2.43.0
+
--- /dev/null
+From c9062a55d6baa1c6f1d64ef6331505661589620b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Sep 2023 17:22:10 +0200
+Subject: drm/tegra: hdmi: Fix some error handling paths in tegra_hdmi_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 643ae131b8598fb2940c92c7d23fe62823a119c8 ]
+
+If an error occurs after calling tegra_output_probe(),
+tegra_output_remove() should be called as already done in the remove
+function.
+
+Fixes: 59d29c0ec93f ("drm/tegra: Allocate resources at probe time")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/9b7c564eb71977678b20abd73ee52001a51cf327.1693667005.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tegra/hdmi.c | 20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
+index f83d9041327f0..c66764c0bd250 100644
+--- a/drivers/gpu/drm/tegra/hdmi.c
++++ b/drivers/gpu/drm/tegra/hdmi.c
+@@ -1838,12 +1838,14 @@ static int tegra_hdmi_probe(struct platform_device *pdev)
+ return err;
+
+ hdmi->regs = devm_platform_ioremap_resource(pdev, 0);
+- if (IS_ERR(hdmi->regs))
+- return PTR_ERR(hdmi->regs);
++ if (IS_ERR(hdmi->regs)) {
++ err = PTR_ERR(hdmi->regs);
++ goto remove;
++ }
+
+ err = platform_get_irq(pdev, 0);
+ if (err < 0)
+- return err;
++ goto remove;
+
+ hdmi->irq = err;
+
+@@ -1852,18 +1854,18 @@ static int tegra_hdmi_probe(struct platform_device *pdev)
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n",
+ hdmi->irq, err);
+- return err;
++ goto remove;
+ }
+
+ platform_set_drvdata(pdev, hdmi);
+
+ err = devm_pm_runtime_enable(&pdev->dev);
+ if (err)
+- return err;
++ goto remove;
+
+ err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
+ if (err)
+- return err;
++ goto remove;
+
+ INIT_LIST_HEAD(&hdmi->client.list);
+ hdmi->client.ops = &hdmi_client_ops;
+@@ -1873,10 +1875,14 @@ static int tegra_hdmi_probe(struct platform_device *pdev)
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to register host1x client: %d\n",
+ err);
+- return err;
++ goto remove;
+ }
+
+ return 0;
++
++remove:
++ tegra_output_remove(&hdmi->output);
++ return err;
+ }
+
+ static int tegra_hdmi_remove(struct platform_device *pdev)
+--
+2.43.0
+
--- /dev/null
+From 78f27c23f2a6287718b7f82e290455ae61720f41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Sep 2023 17:22:13 +0200
+Subject: drm/tegra: output: Fix missing i2c_put_adapter() in the error
+ handling paths of tegra_output_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 2db4578ef6ffb2b52115ca0ebf897b60ec559556 ]
+
+If an error occurs after a successful of_get_i2c_adapter_by_node() call, it
+should be undone by a corresponding i2c_put_adapter().
+
+Add the missing i2c_put_adapter() call.
+
+Fixes: 9be7d864cf07 ("drm/tegra: Implement panel support")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/b38604178991e1f08b2cda219103be266be2d680.1693667005.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tegra/output.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c
+index 47d26b5d99456..7ccd010a821b7 100644
+--- a/drivers/gpu/drm/tegra/output.c
++++ b/drivers/gpu/drm/tegra/output.c
+@@ -139,8 +139,10 @@ int tegra_output_probe(struct tegra_output *output)
+ GPIOD_IN,
+ "HDMI hotplug detect");
+ if (IS_ERR(output->hpd_gpio)) {
+- if (PTR_ERR(output->hpd_gpio) != -ENOENT)
+- return PTR_ERR(output->hpd_gpio);
++ if (PTR_ERR(output->hpd_gpio) != -ENOENT) {
++ err = PTR_ERR(output->hpd_gpio);
++ goto put_i2c;
++ }
+
+ output->hpd_gpio = NULL;
+ }
+@@ -149,7 +151,7 @@ int tegra_output_probe(struct tegra_output *output)
+ err = gpiod_to_irq(output->hpd_gpio);
+ if (err < 0) {
+ dev_err(output->dev, "gpiod_to_irq(): %d\n", err);
+- return err;
++ goto put_i2c;
+ }
+
+ output->hpd_irq = err;
+@@ -162,7 +164,7 @@ int tegra_output_probe(struct tegra_output *output)
+ if (err < 0) {
+ dev_err(output->dev, "failed to request IRQ#%u: %d\n",
+ output->hpd_irq, err);
+- return err;
++ goto put_i2c;
+ }
+
+ output->connector.polled = DRM_CONNECTOR_POLL_HPD;
+@@ -176,6 +178,12 @@ int tegra_output_probe(struct tegra_output *output)
+ }
+
+ return 0;
++
++put_i2c:
++ if (output->ddc)
++ i2c_put_adapter(output->ddc);
++
++ return err;
+ }
+
+ void tegra_output_remove(struct tegra_output *output)
+--
+2.43.0
+
--- /dev/null
+From ed399cf8216f46c0d0a18a822454c7f76292493e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Dec 2023 12:33:55 +0300
+Subject: drm/tegra: put drm_gem_object ref on error in tegra_fb_create
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit 32e5a120a5105bce01561978ee55aee8e40ac0dc ]
+
+Inside tegra_fb_create(), drm_gem_object_lookup() increments ref count of
+the found object. But if the following size check fails then the last
+found object's ref count should be put there as the unreferencing loop
+can't detect this situation.
+
+Found by Linux Verification Center (linuxtesting.org).
+
+Fixes: de2ba664c30f ("gpu: host1x: drm: Add memory manager and fb")
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231215093356.12067-1-pchelkin@ispras.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tegra/fb.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
+index 9291209154a7a..a688ecf08451e 100644
+--- a/drivers/gpu/drm/tegra/fb.c
++++ b/drivers/gpu/drm/tegra/fb.c
+@@ -166,6 +166,7 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
+
+ if (gem->size < size) {
+ err = -EINVAL;
++ drm_gem_object_put(gem);
+ goto unreference;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 070ceb04178334d993b0f23906773a2458e7a8cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Sep 2023 17:22:12 +0200
+Subject: drm/tegra: rgb: Fix missing clk_put() in the error handling paths of
+ tegra_dc_rgb_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 45c8034db47842b25a3ab6139d71e13b4e67b9b3 ]
+
+If clk_get_sys(..., "pll_d2_out0") fails, the clk_get_sys() call must be
+undone.
+
+Add the missing clk_put and a new 'put_pll_d_out0' label in the error
+handling path, and use it.
+
+Fixes: 0c921b6d4ba0 ("drm/tegra: dc: rgb: Allow changing PLLD rate on Tegra30+")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/0182895ead4e4730426616b0d9995954c960b634.1693667005.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tegra/rgb.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
+index 5e95943021887..86e55e5d12b39 100644
+--- a/drivers/gpu/drm/tegra/rgb.c
++++ b/drivers/gpu/drm/tegra/rgb.c
+@@ -243,7 +243,7 @@ int tegra_dc_rgb_probe(struct tegra_dc *dc)
+ if (IS_ERR(rgb->pll_d2_out0)) {
+ err = PTR_ERR(rgb->pll_d2_out0);
+ dev_err(dc->dev, "failed to get pll_d2_out0: %d\n", err);
+- goto remove;
++ goto put_pll;
+ }
+ }
+
+@@ -251,6 +251,8 @@ int tegra_dc_rgb_probe(struct tegra_dc *dc)
+
+ return 0;
+
++put_pll:
++ clk_put(rgb->pll_d_out0);
+ remove:
+ tegra_output_remove(&rgb->output);
+ return err;
+--
+2.43.0
+
--- /dev/null
+From a339db791f363f312e550d2561fd351f7d5106b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Sep 2023 17:22:11 +0200
+Subject: drm/tegra: rgb: Fix some error handling paths in tegra_dc_rgb_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit bc456b5d93dbfdbd89f2a036f4f3d8026595f9e4 ]
+
+If an error occurs after calling tegra_output_probe(),
+tegra_output_remove() should be called as already done in the remove
+function.
+
+Fixes: 59d29c0ec93f ("drm/tegra: Allocate resources at probe time")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/0001f61eb89048bc36241629b564195689cf54b6.1693667005.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tegra/rgb.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
+index ff8fce36d2aa1..5e95943021887 100644
+--- a/drivers/gpu/drm/tegra/rgb.c
++++ b/drivers/gpu/drm/tegra/rgb.c
+@@ -214,26 +214,28 @@ int tegra_dc_rgb_probe(struct tegra_dc *dc)
+ rgb->clk = devm_clk_get(dc->dev, NULL);
+ if (IS_ERR(rgb->clk)) {
+ dev_err(dc->dev, "failed to get clock\n");
+- return PTR_ERR(rgb->clk);
++ err = PTR_ERR(rgb->clk);
++ goto remove;
+ }
+
+ rgb->clk_parent = devm_clk_get(dc->dev, "parent");
+ if (IS_ERR(rgb->clk_parent)) {
+ dev_err(dc->dev, "failed to get parent clock\n");
+- return PTR_ERR(rgb->clk_parent);
++ err = PTR_ERR(rgb->clk_parent);
++ goto remove;
+ }
+
+ err = clk_set_parent(rgb->clk, rgb->clk_parent);
+ if (err < 0) {
+ dev_err(dc->dev, "failed to set parent clock: %d\n", err);
+- return err;
++ goto remove;
+ }
+
+ rgb->pll_d_out0 = clk_get_sys(NULL, "pll_d_out0");
+ if (IS_ERR(rgb->pll_d_out0)) {
+ err = PTR_ERR(rgb->pll_d_out0);
+ dev_err(dc->dev, "failed to get pll_d_out0: %d\n", err);
+- return err;
++ goto remove;
+ }
+
+ if (dc->soc->has_pll_d2_out0) {
+@@ -241,13 +243,17 @@ int tegra_dc_rgb_probe(struct tegra_dc *dc)
+ if (IS_ERR(rgb->pll_d2_out0)) {
+ err = PTR_ERR(rgb->pll_d2_out0);
+ dev_err(dc->dev, "failed to get pll_d2_out0: %d\n", err);
+- return err;
++ goto remove;
+ }
+ }
+
+ dc->rgb = &rgb->output;
+
+ return 0;
++
++remove:
++ tegra_output_remove(&rgb->output);
++ return err;
+ }
+
+ int tegra_dc_rgb_remove(struct tegra_dc *dc)
+--
+2.43.0
+
--- /dev/null
+From aaabdc97ce179915b0b4494a2527671392e063db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Feb 2024 10:16:36 +0200
+Subject: drm/tidss: Fix initial plane zpos values
+
+From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+
+[ Upstream commit 3ec948ccb2c4b99e8fbfdd950adbe92ea577b395 ]
+
+When the driver sets up the zpos property it sets the default zpos value
+to the HW id of the plane. That is fine as such, but as on many DSS
+versions the driver arranges the DRM planes in a different order than
+the HW planes (to keep the non-scalable planes first), this leads to odd
+initial zpos values. An example is J721e, where the initial zpos values
+for DRM planes are 1, 3, 0, 2.
+
+In theory the userspace should configure the zpos values properly when
+using multiple planes, and in that sense the initial zpos values
+shouldn't matter, but there's really no reason not to fix this and help
+the userspace apps which don't handle zpos perfectly. In particular,
+some versions of Weston seem to have issues dealing with the planes
+with the current default zpos values.
+
+So let's change the zpos values for the DRM planes to 0, 1, 2, 3.
+
+Another option would be to configure the planes marked as primary planes
+to zpos 0. On a two display system this would give us plane zpos values
+of 0, 0, 1, 2. The end result and behavior would be very similar in this
+option, and I'm not aware that this would actually help us in any way.
+So, to keep the code simple, I opted for the 0, 1, 2, 3 values.
+
+Fixes: 32a1795f57ee ("drm/tidss: New driver for TI Keystone platform Display SubSystem")
+Reviewed-by: Aradhya Bhatia <a-bhatia1@ti.com>
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240213-tidss-fixes-v1-1-d709e8dfa505@ideasonboard.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tidss/tidss_plane.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/tidss/tidss_plane.c b/drivers/gpu/drm/tidss/tidss_plane.c
+index 42d50ec5526d7..435b3b66ae632 100644
+--- a/drivers/gpu/drm/tidss/tidss_plane.c
++++ b/drivers/gpu/drm/tidss/tidss_plane.c
+@@ -211,7 +211,7 @@ struct tidss_plane *tidss_plane_create(struct tidss_device *tidss,
+
+ drm_plane_helper_add(&tplane->plane, &tidss_plane_helper_funcs);
+
+- drm_plane_create_zpos_property(&tplane->plane, hw_plane_id, 0,
++ drm_plane_create_zpos_property(&tplane->plane, tidss->num_planes, 0,
+ num_planes - 1);
+
+ ret = drm_plane_create_color_properties(&tplane->plane,
+--
+2.43.0
+
--- /dev/null
+From 0fb8cab25992c92d2e7d9fcbea3989f0defda74d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Feb 2024 10:16:37 +0200
+Subject: drm/tidss: Fix sync-lost issue with two displays
+
+From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+
+[ Upstream commit c079e2e113f2ec2803ba859bbb442a6ab82c96bd ]
+
+A sync lost issue can be observed with two displays, when moving a plane
+from one disabled display to an another disabled display, and then
+enabling the display to which the plane was moved to. The exact
+requirements for this to trigger are not clear.
+
+It looks like the issue is that the layers are left enabled in the first
+display's OVR registers. Even if the corresponding VP is disabled, it
+still causes an issue, as if the disabled VP and its OVR would still be
+in use, leading to the same VID being used by two OVRs. However, this is
+just speculation based on testing the DSS behavior.
+
+Experimentation shows that as a workaround, we can disable all the
+layers in the OVR when disabling a VP. There should be no downside to
+this, as the OVR is anyway effectively disabled if its VP is disabled,
+and it seems to solve the sync lost issue.
+
+However, there may be a bigger issue in play here, related to J721e
+erratum i2097 ("DSS: Disabling a Layer Connected to Overlay May Result
+in Synclost During the Next Frame"). Experimentation also shows that the
+OVR's CHANNELIN field has similar issue. So we may need to revisit this
+when we find out more about the core issue.
+
+Fixes: 32a1795f57ee ("drm/tidss: New driver for TI Keystone platform Display SubSystem")
+Reviewed-by: Aradhya Bhatia <a-bhatia1@ti.com>
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240213-tidss-fixes-v1-2-d709e8dfa505@ideasonboard.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tidss/tidss_crtc.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tidss_crtc.c
+index cb66a425dd200..896a77853ebc5 100644
+--- a/drivers/gpu/drm/tidss/tidss_crtc.c
++++ b/drivers/gpu/drm/tidss/tidss_crtc.c
+@@ -270,6 +270,16 @@ static void tidss_crtc_atomic_disable(struct drm_crtc *crtc,
+
+ reinit_completion(&tcrtc->framedone_completion);
+
++ /*
++ * If a layer is left enabled when the videoport is disabled, and the
++ * vid pipeline that was used for the layer is taken into use on
++ * another videoport, the DSS will report sync lost issues. Disable all
++ * the layers here as a work-around.
++ */
++ for (u32 layer = 0; layer < tidss->feat->num_planes; layer++)
++ dispc_ovr_enable_layer(tidss->dispc, tcrtc->hw_videoport, layer,
++ false);
++
+ dispc_vp_disable(tidss->dispc, tcrtc->hw_videoport);
+
+ if (!wait_for_completion_timeout(&tcrtc->framedone_completion,
+--
+2.43.0
+
--- /dev/null
+From ced9c6896769a3e5008d57c18cdd62218f23b36f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Dec 2023 17:14:16 +0800
+Subject: drm/vmwgfx: fix a memleak in vmw_gmrid_man_get_node
+
+From: Zhipeng Lu <alexious@zju.edu.cn>
+
+[ Upstream commit 89709105a6091948ffb6ec2427954cbfe45358ce ]
+
+When ida_alloc_max fails, resources allocated before should be freed,
+including *res allocated by kmalloc and ttm_resource_init.
+
+Fixes: d3bcb4b02fe9 ("drm/vmwgfx: switch the TTM backends to self alloc")
+Signed-off-by: Zhipeng Lu <alexious@zju.edu.cn>
+Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20231204091416.3308430-1-alexious@zju.edu.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
+index 60e3cc537f365..b9e5c8cd31001 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
+@@ -65,8 +65,11 @@ static int vmw_gmrid_man_get_node(struct ttm_resource_manager *man,
+ ttm_resource_init(bo, place, *res);
+
+ id = ida_alloc_max(&gman->gmr_ida, gman->max_gmr_ids - 1, GFP_KERNEL);
+- if (id < 0)
++ if (id < 0) {
++ ttm_resource_fini(man, *res);
++ kfree(*res);
+ return id;
++ }
+
+ spin_lock(&gman->lock);
+
+--
+2.43.0
+
--- /dev/null
+From 8a23fa8e79988c92b8501e6a8d012315ec481588 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jan 2024 12:37:26 +0530
+Subject: dt-bindings: clock: qcom: Add missing UFS QREF clocks
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 26447dad8119fd084d7c6f167c3026700b701666 ]
+
+Add missing QREF clocks for UFS MEM and UFS CARD controllers.
+
+Fixes: 0fadcdfdcf57 ("dt-bindings: clock: Add SC8180x GCC binding")
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20240131-ufs-phy-clock-v3-3-58a49d2f4605@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: bb5c0229285f ("clk: qcom: gcc-sc8180x: Add missing UFS QREF clocks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/dt-bindings/clock/qcom,gcc-sc8180x.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/dt-bindings/clock/qcom,gcc-sc8180x.h b/include/dt-bindings/clock/qcom,gcc-sc8180x.h
+index e893415ae13d0..90c6e021a0356 100644
+--- a/include/dt-bindings/clock/qcom,gcc-sc8180x.h
++++ b/include/dt-bindings/clock/qcom,gcc-sc8180x.h
+@@ -246,6 +246,8 @@
+ #define GCC_PCIE_3_CLKREF_CLK 236
+ #define GCC_USB3_PRIM_CLKREF_CLK 237
+ #define GCC_USB3_SEC_CLKREF_CLK 238
++#define GCC_UFS_MEM_CLKREF_EN 239
++#define GCC_UFS_CARD_CLKREF_EN 240
+
+ #define GCC_EMAC_BCR 0
+ #define GCC_GPU_BCR 1
+--
+2.43.0
+
--- /dev/null
+From 561002d2c2fdd4d11abf4195b07ba87c851c8d6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Feb 2024 12:32:05 -0800
+Subject: f2fs: check number of blocks in a current section
+
+From: Jaegeuk Kim <jaegeuk@kernel.org>
+
+[ Upstream commit 7af2df0f67a1469762e59be3726a803882d83f6f ]
+
+In cfd66bb715fd ("f2fs: fix deadloop in foreground GC"), we needed to check
+the number of blocks in a section instead of the segment.
+
+Fixes: cfd66bb715fd ("f2fs: fix deadloop in foreground GC")
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/segment.h | 17 ++++++++---------
+ 1 file changed, 8 insertions(+), 9 deletions(-)
+
+diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
+index f3951e8ad3948..aa9ad85e0901d 100644
+--- a/fs/f2fs/segment.h
++++ b/fs/f2fs/segment.h
+@@ -586,23 +586,22 @@ static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi,
+ unsigned int node_blocks, unsigned int dent_blocks)
+ {
+
+- unsigned int segno, left_blocks;
++ unsigned segno, left_blocks;
+ int i;
+
+- /* check current node segment */
++ /* check current node sections in the worst case. */
+ for (i = CURSEG_HOT_NODE; i <= CURSEG_COLD_NODE; i++) {
+ segno = CURSEG_I(sbi, i)->segno;
+- left_blocks = f2fs_usable_blks_in_seg(sbi, segno) -
+- get_seg_entry(sbi, segno)->ckpt_valid_blocks;
+-
++ left_blocks = CAP_BLKS_PER_SEC(sbi) -
++ get_ckpt_valid_blocks(sbi, segno, true);
+ if (node_blocks > left_blocks)
+ return false;
+ }
+
+- /* check current data segment */
++ /* check current data section for dentry blocks. */
+ segno = CURSEG_I(sbi, CURSEG_HOT_DATA)->segno;
+- left_blocks = f2fs_usable_blks_in_seg(sbi, segno) -
+- get_seg_entry(sbi, segno)->ckpt_valid_blocks;
++ left_blocks = CAP_BLKS_PER_SEC(sbi) -
++ get_ckpt_valid_blocks(sbi, segno, true);
+ if (dent_blocks > left_blocks)
+ return false;
+ return true;
+@@ -651,7 +650,7 @@ static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi,
+
+ if (free_secs > upper_secs)
+ return false;
+- else if (free_secs <= lower_secs)
++ if (free_secs <= lower_secs)
+ return true;
+ return !curseg_space;
+ }
+--
+2.43.0
+
--- /dev/null
+From a08c9742c04b85dbf6cbda39f4165158a7f518b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Mar 2024 11:47:46 +0800
+Subject: f2fs: compress: fix reserve_cblocks counting error when out of space
+
+From: Xiuhong Wang <xiuhong.wang@unisoc.com>
+
+[ Upstream commit 2f6d721e14b69d6e1251f69fa238b48e8374e25f ]
+
+When a file only needs one direct_node, performing the following
+operations will cause the file to be unrepairable:
+
+unisoc # ./f2fs_io compress test.apk
+unisoc #df -h | grep dm-48
+/dev/block/dm-48 112G 112G 1.2M 100% /data
+
+unisoc # ./f2fs_io release_cblocks test.apk
+924
+unisoc # df -h | grep dm-48
+/dev/block/dm-48 112G 112G 4.8M 100% /data
+
+unisoc # dd if=/dev/random of=file4 bs=1M count=3
+3145728 bytes (3.0 M) copied, 0.025 s, 120 M/s
+unisoc # df -h | grep dm-48
+/dev/block/dm-48 112G 112G 1.8M 100% /data
+
+unisoc # ./f2fs_io reserve_cblocks test.apk
+F2FS_IOC_RESERVE_COMPRESS_BLOCKS failed: No space left on device
+
+adb reboot
+unisoc # df -h | grep dm-48
+/dev/block/dm-48 112G 112G 11M 100% /data
+unisoc # ./f2fs_io reserve_cblocks test.apk
+0
+
+This is because the file has only one direct_node. After returning
+to -ENOSPC, reserved_blocks += ret will not be executed. As a result,
+the reserved_blocks at this time is still 0, which is not the real
+number of reserved blocks. Therefore, fsck cannot be set to repair
+the file.
+
+After this patch, the fsck flag will be set to fix this problem.
+
+unisoc # df -h | grep dm-48
+/dev/block/dm-48 112G 112G 1.8M 100% /data
+unisoc # ./f2fs_io reserve_cblocks test.apk
+F2FS_IOC_RESERVE_COMPRESS_BLOCKS failed: No space left on device
+
+adb reboot then fsck will be executed
+unisoc # df -h | grep dm-48
+/dev/block/dm-48 112G 112G 11M 100% /data
+unisoc # ./f2fs_io reserve_cblocks test.apk
+924
+
+Fixes: c75488fb4d82 ("f2fs: introduce F2FS_IOC_RESERVE_COMPRESS_BLOCKS")
+Signed-off-by: Xiuhong Wang <xiuhong.wang@unisoc.com>
+Signed-off-by: Zhiguo Niu <zhiguo.niu@unisoc.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 5dbd874ba3d8d..2fbc8d89c600b 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -3561,10 +3561,10 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
+ return ret;
+ }
+
+-static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count)
++static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count,
++ unsigned int *reserved_blocks)
+ {
+ struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
+- unsigned int reserved_blocks = 0;
+ int cluster_size = F2FS_I(dn->inode)->i_cluster_size;
+ block_t blkaddr;
+ int i;
+@@ -3628,12 +3628,12 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count)
+
+ f2fs_i_compr_blocks_update(dn->inode, compr_blocks, true);
+
+- reserved_blocks += reserved;
++ *reserved_blocks += reserved;
+ next:
+ count -= cluster_size;
+ }
+
+- return reserved_blocks;
++ return 0;
+ }
+
+ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
+@@ -3694,7 +3694,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
+ count = min(end_offset - dn.ofs_in_node, last_idx - page_idx);
+ count = round_up(count, F2FS_I(inode)->i_cluster_size);
+
+- ret = reserve_compress_blocks(&dn, count);
++ ret = reserve_compress_blocks(&dn, count, &reserved_blocks);
+
+ f2fs_put_dnode(&dn);
+
+@@ -3702,13 +3702,12 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
+ break;
+
+ page_idx += count;
+- reserved_blocks += ret;
+ }
+
+ filemap_invalidate_unlock(inode->i_mapping);
+ f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+
+- if (ret >= 0) {
++ if (!ret) {
+ clear_inode_flag(inode, FI_COMPRESS_RELEASED);
+ inode->i_ctime = current_time(inode);
+ f2fs_mark_inode_dirty_sync(inode, true);
+@@ -3717,7 +3716,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
+ inode_unlock(inode);
+ mnt_drop_write_file(filp);
+
+- if (ret >= 0) {
++ if (!ret) {
+ ret = put_user(reserved_blocks, (u64 __user *)arg);
+ } else if (reserved_blocks &&
+ atomic_read(&F2FS_I(inode)->i_compr_blocks)) {
+--
+2.43.0
+
--- /dev/null
+From c6c64acae4bf47aced41402f74dc7e8bfd86a103 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 Jan 2024 03:41:30 +0800
+Subject: f2fs: compress: fix to avoid inconsistence bewteen i_blocks and dnode
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 54607494875edd636aff3c21ace3ad9a7da758a9 ]
+
+In reserve_compress_blocks(), we update blkaddrs of dnode in prior to
+inc_valid_block_count(), it may cause inconsistent status bewteen
+i_blocks and blkaddrs once inc_valid_block_count() fails.
+
+To fix this issue, it needs to reverse their invoking order.
+
+Fixes: c75488fb4d82 ("f2fs: introduce F2FS_IOC_RESERVE_COMPRESS_BLOCKS")
+Reviewed-by: Daeho Jeong <daehojeong@google.com>
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/data.c | 5 +++--
+ fs/f2fs/f2fs.h | 7 ++++++-
+ fs/f2fs/file.c | 26 ++++++++++++++------------
+ fs/f2fs/segment.c | 2 +-
+ 4 files changed, 24 insertions(+), 16 deletions(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 1aa7d443cf364..b83b8ac29f430 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -1142,7 +1142,8 @@ int f2fs_reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count)
+
+ if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
+ return -EPERM;
+- if (unlikely((err = inc_valid_block_count(sbi, dn->inode, &count))))
++ err = inc_valid_block_count(sbi, dn->inode, &count, true);
++ if (unlikely(err))
+ return err;
+
+ trace_f2fs_reserve_new_blocks(dn->inode, dn->nid,
+@@ -1413,7 +1414,7 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
+
+ dn->data_blkaddr = f2fs_data_blkaddr(dn);
+ if (dn->data_blkaddr == NULL_ADDR) {
+- err = inc_valid_block_count(sbi, dn->inode, &count);
++ err = inc_valid_block_count(sbi, dn->inode, &count, true);
+ if (unlikely(err))
+ return err;
+ }
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 7f34c7d0d156e..2afb91471b535 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -2286,7 +2286,7 @@ static inline bool __allow_reserved_blocks(struct f2fs_sb_info *sbi,
+
+ static inline void f2fs_i_blocks_write(struct inode *, block_t, bool, bool);
+ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
+- struct inode *inode, blkcnt_t *count)
++ struct inode *inode, blkcnt_t *count, bool partial)
+ {
+ blkcnt_t diff = 0, release = 0;
+ block_t avail_user_block_count;
+@@ -2327,6 +2327,11 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
+ avail_user_block_count = 0;
+ }
+ if (unlikely(sbi->total_valid_block_count > avail_user_block_count)) {
++ if (!partial) {
++ spin_unlock(&sbi->stat_lock);
++ goto enospc;
++ }
++
+ diff = sbi->total_valid_block_count - avail_user_block_count;
+ if (diff > *count)
+ diff = *count;
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index aa3ded9825f0c..96b59c87f30c7 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -3587,14 +3587,16 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count)
+ blkcnt_t reserved;
+ int ret;
+
+- for (i = 0; i < cluster_size; i++, dn->ofs_in_node++) {
+- blkaddr = f2fs_data_blkaddr(dn);
++ for (i = 0; i < cluster_size; i++) {
++ blkaddr = data_blkaddr(dn->inode, dn->node_page,
++ dn->ofs_in_node + i);
+
+ if (i == 0) {
+- if (blkaddr == COMPRESS_ADDR)
+- continue;
+- dn->ofs_in_node += cluster_size;
+- goto next;
++ if (blkaddr != COMPRESS_ADDR) {
++ dn->ofs_in_node += cluster_size;
++ goto next;
++ }
++ continue;
+ }
+
+ /*
+@@ -3607,8 +3609,6 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count)
+ compr_blocks++;
+ continue;
+ }
+-
+- f2fs_set_data_blkaddr(dn, NEW_ADDR);
+ }
+
+ reserved = cluster_size - compr_blocks;
+@@ -3617,12 +3617,14 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count)
+ if (reserved == 1)
+ goto next;
+
+- ret = inc_valid_block_count(sbi, dn->inode, &reserved);
+- if (ret)
++ ret = inc_valid_block_count(sbi, dn->inode, &reserved, false);
++ if (unlikely(ret))
+ return ret;
+
+- if (reserved != cluster_size - compr_blocks)
+- return -ENOSPC;
++ for (i = 0; i < cluster_size; i++, dn->ofs_in_node++) {
++ if (f2fs_data_blkaddr(dn) == NULL_ADDR)
++ f2fs_set_data_blkaddr(dn, NEW_ADDR);
++ }
+
+ f2fs_i_compr_blocks_update(dn->inode, compr_blocks, true);
+
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index a3dabec1f216a..aa1ba2fdfe00d 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -247,7 +247,7 @@ static int __replace_atomic_write_block(struct inode *inode, pgoff_t index,
+ } else {
+ blkcnt_t count = 1;
+
+- err = inc_valid_block_count(sbi, inode, &count);
++ err = inc_valid_block_count(sbi, inode, &count, true);
+ if (err) {
+ f2fs_put_dnode(&dn);
+ return err;
+--
+2.43.0
+
--- /dev/null
+From ad7939a85d37000461d8d31fd47d1510cee1dd92 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Feb 2024 10:28:44 +0800
+Subject: f2fs: compress: fix to check compress flag w/ .i_sem lock
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit ea59b12ac69774c08aa95cd5b6100700ea0cce97 ]
+
+It needs to check compress flag w/ .i_sem lock, otherwise, compressed
+inode may be disabled after the check condition, it's not needed to
+set compress option on non-compress inode.
+
+Fixes: e1e8debec656 ("f2fs: add F2FS_IOC_SET_COMPRESS_OPTION ioctl")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 96b59c87f30c7..be4cab941d299 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -3967,16 +3967,20 @@ static int f2fs_ioc_set_compress_option(struct file *filp, unsigned long arg)
+ sizeof(option)))
+ return -EFAULT;
+
+- if (!f2fs_compressed_file(inode) ||
+- option.log_cluster_size < MIN_COMPRESS_LOG_SIZE ||
+- option.log_cluster_size > MAX_COMPRESS_LOG_SIZE ||
+- option.algorithm >= COMPRESS_MAX)
++ if (option.log_cluster_size < MIN_COMPRESS_LOG_SIZE ||
++ option.log_cluster_size > MAX_COMPRESS_LOG_SIZE ||
++ option.algorithm >= COMPRESS_MAX)
+ return -EINVAL;
+
+ file_start_write(filp);
+ inode_lock(inode);
+
+ f2fs_down_write(&F2FS_I(inode)->i_sem);
++ if (!f2fs_compressed_file(inode)) {
++ ret = -EINVAL;
++ goto out;
++ }
++
+ if (f2fs_is_mmap_file(inode) || get_dirty_pages(inode)) {
+ ret = -EBUSY;
+ goto out;
+--
+2.43.0
+
--- /dev/null
+From 934b2f313d5c559a3c56606bccb8f872d845e02b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 Jan 2024 03:41:29 +0800
+Subject: f2fs: compress: fix to check unreleased compressed cluster
+
+From: Sheng Yong <shengyong@oppo.com>
+
+[ Upstream commit eb8fbaa53374e0a2d4381190abfe708481517bbb ]
+
+Compressed cluster may not be released due to we can fail in
+release_compress_blocks(), fix to handle reserved compressed
+cluster correctly in reserve_compress_blocks().
+
+Fixes: 4c8ff7095bef ("f2fs: support data compression")
+Signed-off-by: Sheng Yong <shengyong@oppo.com>
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 46e4960a9dcf7..6c9f03e3be8e9 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -3609,7 +3609,13 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count)
+ goto next;
+ }
+
+- if (__is_valid_data_blkaddr(blkaddr)) {
++ /*
++ * compressed cluster was not released due to it
++ * fails in release_compress_blocks(), so NEW_ADDR
++ * is a possible case.
++ */
++ if (blkaddr == NEW_ADDR ||
++ __is_valid_data_blkaddr(blkaddr)) {
+ compr_blocks++;
+ continue;
+ }
+@@ -3619,6 +3625,11 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count)
+ }
+
+ reserved = cluster_size - compr_blocks;
++
++ /* for the case all blocks in cluster were reserved */
++ if (reserved == 1)
++ goto next;
++
+ ret = inc_valid_block_count(sbi, dn->inode, &reserved);
+ if (ret)
+ return ret;
+--
+2.43.0
+
--- /dev/null
+From e5493f67739ff923d72f1d29640ae65d8c200de3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Feb 2024 00:08:18 +0800
+Subject: f2fs: compress: fix to check zstd compress level correctly in mount
+ option
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit e39602da752cd1d0462e3fa04074146f6f2803f6 ]
+
+f2fs only support to config zstd compress level w/ a positive number due
+to layout design, but since commit e0c1b49f5b67 ("lib: zstd: Upgrade to
+latest upstream zstd version 1.4.10"), zstd supports negative compress
+level, so that zstd_min_clevel() may return a negative number, then w/
+below mount option, .compress_level can be configed w/ a negative number,
+which is not allowed to f2fs, let's add check condition to avoid it.
+
+mount -o compress_algorithm=zstd:4294967295 /dev/sdx /mnt/f2fs
+
+Fixes: 00e120b5e4b5 ("f2fs: assign default compression level")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/super.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 0c0d0671febea..c529ce5d986cc 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -649,7 +649,7 @@ static int f2fs_set_lz4hc_level(struct f2fs_sb_info *sbi, const char *str)
+ #ifdef CONFIG_F2FS_FS_ZSTD
+ static int f2fs_set_zstd_level(struct f2fs_sb_info *sbi, const char *str)
+ {
+- unsigned int level;
++ int level;
+ int len = 4;
+
+ if (strlen(str) == len) {
+@@ -663,9 +663,15 @@ static int f2fs_set_zstd_level(struct f2fs_sb_info *sbi, const char *str)
+ f2fs_info(sbi, "wrong format, e.g. <alg_name>:<compr_level>");
+ return -EINVAL;
+ }
+- if (kstrtouint(str + 1, 10, &level))
++ if (kstrtoint(str + 1, 10, &level))
+ return -EINVAL;
+
++ /* f2fs does not support negative compress level now */
++ if (level < 0) {
++ f2fs_info(sbi, "do not support negative compress level: %d", level);
++ return -ERANGE;
++ }
++
+ if (!f2fs_is_compress_level_valid(COMPRESS_ZSTD, level)) {
+ f2fs_info(sbi, "invalid zstd compress level: %d", level);
+ return -EINVAL;
+--
+2.43.0
+
--- /dev/null
+From 0fa828d92c7ac6b804f91149a1bc4b2ea00f79b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jan 2024 10:23:13 +0800
+Subject: f2fs: compress: fix to cover f2fs_disable_compressed_file() w/ i_sem
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 2f9420d3a94aeebd92db88f00f4f2f1a3bd3f6cf ]
+
+- f2fs_disable_compressed_file
+ - check inode_has_data
+ - f2fs_file_mmap
+ - mkwrite
+ - f2fs_get_block_locked
+ : update metadata in compressed
+ inode's disk layout
+ - fi->i_flags &= ~F2FS_COMPR_FL
+ - clear_inode_flag(inode, FI_COMPRESSED_FILE);
+
+we should use i_sem lock to prevent above race case.
+
+Fixes: 4c8ff7095bef ("f2fs: support data compression")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/f2fs.h | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 2afb91471b535..a81091a5e282d 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -4367,15 +4367,24 @@ static inline bool f2fs_disable_compressed_file(struct inode *inode)
+ {
+ struct f2fs_inode_info *fi = F2FS_I(inode);
+
+- if (!f2fs_compressed_file(inode))
++ f2fs_down_write(&F2FS_I(inode)->i_sem);
++
++ if (!f2fs_compressed_file(inode)) {
++ f2fs_up_write(&F2FS_I(inode)->i_sem);
+ return true;
+- if (S_ISREG(inode->i_mode) && F2FS_HAS_BLOCKS(inode))
++ }
++ if (f2fs_is_mmap_file(inode) ||
++ (S_ISREG(inode->i_mode) && F2FS_HAS_BLOCKS(inode))) {
++ f2fs_up_write(&F2FS_I(inode)->i_sem);
+ return false;
++ }
+
+ fi->i_flags &= ~F2FS_COMPR_FL;
+ stat_dec_compr_inode(inode);
+ clear_inode_flag(inode, FI_COMPRESSED_FILE);
+ f2fs_mark_inode_dirty_sync(inode, true);
++
++ f2fs_up_write(&F2FS_I(inode)->i_sem);
+ return true;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 43ee85ea9c8b176755fc457dfaf78de0bea34bb0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 Jan 2024 03:41:28 +0800
+Subject: f2fs: compress: fix to cover normal cluster write with cp_rwsem
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit fd244524c2cf07b5f4c3fe8abd6a99225c76544b ]
+
+When we overwrite compressed cluster w/ normal cluster, we should
+not unlock cp_rwsem during f2fs_write_raw_pages(), otherwise data
+will be corrupted if partial blocks were persisted before CP & SPOR,
+due to cluster metadata wasn't updated atomically.
+
+Fixes: 4c8ff7095bef ("f2fs: support data compression")
+Reviewed-by: Daeho Jeong <daehojeong@google.com>
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/compress.c | 27 ++++++++++++++++++---------
+ fs/f2fs/data.c | 3 ++-
+ 2 files changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
+index 459bf10f297a2..553950962842a 100644
+--- a/fs/f2fs/compress.c
++++ b/fs/f2fs/compress.c
+@@ -1462,12 +1462,14 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page)
+ }
+
+ static int f2fs_write_raw_pages(struct compress_ctx *cc,
+- int *submitted,
++ int *submitted_p,
+ struct writeback_control *wbc,
+ enum iostat_type io_type)
+ {
+ struct address_space *mapping = cc->inode->i_mapping;
+- int _submitted, compr_blocks, ret, i;
++ struct f2fs_sb_info *sbi = F2FS_M_SB(mapping);
++ int submitted, compr_blocks, i;
++ int ret = 0;
+
+ compr_blocks = f2fs_compressed_blocks(cc);
+
+@@ -1482,6 +1484,10 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc,
+ if (compr_blocks < 0)
+ return compr_blocks;
+
++ /* overwrite compressed cluster w/ normal cluster */
++ if (compr_blocks > 0)
++ f2fs_lock_op(sbi);
++
+ for (i = 0; i < cc->cluster_size; i++) {
+ if (!cc->rpages[i])
+ continue;
+@@ -1506,7 +1512,7 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc,
+ if (!clear_page_dirty_for_io(cc->rpages[i]))
+ goto continue_unlock;
+
+- ret = f2fs_write_single_data_page(cc->rpages[i], &_submitted,
++ ret = f2fs_write_single_data_page(cc->rpages[i], &submitted,
+ NULL, NULL, wbc, io_type,
+ compr_blocks, false);
+ if (ret) {
+@@ -1514,26 +1520,29 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc,
+ unlock_page(cc->rpages[i]);
+ ret = 0;
+ } else if (ret == -EAGAIN) {
++ ret = 0;
+ /*
+ * for quota file, just redirty left pages to
+ * avoid deadlock caused by cluster update race
+ * from foreground operation.
+ */
+ if (IS_NOQUOTA(cc->inode))
+- return 0;
+- ret = 0;
++ goto out;
+ f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+ goto retry_write;
+ }
+- return ret;
++ goto out;
+ }
+
+- *submitted += _submitted;
++ *submitted_p += submitted;
+ }
+
+- f2fs_balance_fs(F2FS_M_SB(mapping), true);
++out:
++ if (compr_blocks > 0)
++ f2fs_unlock_op(sbi);
+
+- return 0;
++ f2fs_balance_fs(sbi, true);
++ return ret;
+ }
+
+ int f2fs_write_multi_pages(struct compress_ctx *cc,
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 6f649a60859fc..3f0ba71451c27 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -2779,7 +2779,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
+ .encrypted_page = NULL,
+ .submitted = 0,
+ .compr_blocks = compr_blocks,
+- .need_lock = LOCK_RETRY,
++ .need_lock = compr_blocks ? LOCK_DONE : LOCK_RETRY,
+ .post_read = f2fs_post_read_required(inode) ? 1 : 0,
+ .io_type = io_type,
+ .io_wbc = wbc,
+@@ -2859,6 +2859,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
+ if (err == -EAGAIN) {
+ err = f2fs_do_write_data_page(&fio);
+ if (err == -EAGAIN) {
++ f2fs_bug_on(sbi, compr_blocks);
+ fio.need_lock = LOCK_REQ;
+ err = f2fs_do_write_data_page(&fio);
+ }
+--
+2.43.0
+
--- /dev/null
+From 03703434ffb3160ab1c05017a93293414e75152f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 Jan 2024 03:41:27 +0800
+Subject: f2fs: compress: fix to guarantee persisting compressed blocks by CP
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 8a430dd49e9cb021372b0ad91e60aeef9c6ced00 ]
+
+If data block in compressed cluster is not persisted with metadata
+during checkpoint, after SPOR, the data may be corrupted, let's
+guarantee to write compressed page by checkpoint.
+
+Fixes: 4c8ff7095bef ("f2fs: support data compression")
+Reviewed-by: Daeho Jeong <daehojeong@google.com>
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/compress.c | 4 +++-
+ fs/f2fs/data.c | 17 +++++++++--------
+ fs/f2fs/f2fs.h | 4 +++-
+ 3 files changed, 15 insertions(+), 10 deletions(-)
+
+diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
+index 7d85db7208e14..459bf10f297a2 100644
+--- a/fs/f2fs/compress.c
++++ b/fs/f2fs/compress.c
+@@ -1437,6 +1437,8 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page)
+ struct f2fs_sb_info *sbi = bio->bi_private;
+ struct compress_io_ctx *cic =
+ (struct compress_io_ctx *)page_private(page);
++ enum count_type type = WB_DATA_TYPE(page,
++ f2fs_is_compressed_page(page));
+ int i;
+
+ if (unlikely(bio->bi_status))
+@@ -1444,7 +1446,7 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page)
+
+ f2fs_compress_free_page(page);
+
+- dec_page_count(sbi, F2FS_WB_DATA);
++ dec_page_count(sbi, type);
+
+ if (atomic_dec_return(&cic->pending_pages))
+ return;
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 7b3eb192f9c03..6f649a60859fc 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -50,7 +50,7 @@ void f2fs_destroy_bioset(void)
+ bioset_exit(&f2fs_bioset);
+ }
+
+-static bool __is_cp_guaranteed(struct page *page)
++bool f2fs_is_cp_guaranteed(struct page *page)
+ {
+ struct address_space *mapping = page->mapping;
+ struct inode *inode;
+@@ -67,8 +67,6 @@ static bool __is_cp_guaranteed(struct page *page)
+ S_ISDIR(inode->i_mode))
+ return true;
+
+- if (f2fs_is_compressed_page(page))
+- return false;
+ if ((S_ISREG(inode->i_mode) && IS_NOQUOTA(inode)) ||
+ page_private_gcing(page))
+ return true;
+@@ -327,7 +325,7 @@ static void f2fs_write_end_io(struct bio *bio)
+
+ bio_for_each_segment_all(bvec, bio, iter_all) {
+ struct page *page = bvec->bv_page;
+- enum count_type type = WB_DATA_TYPE(page);
++ enum count_type type = WB_DATA_TYPE(page, false);
+
+ if (page_private_dummy(page)) {
+ clear_page_private_dummy(page);
+@@ -733,7 +731,7 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio)
+ wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE);
+
+ inc_page_count(fio->sbi, is_read_io(fio->op) ?
+- __read_io_type(page) : WB_DATA_TYPE(fio->page));
++ __read_io_type(page) : WB_DATA_TYPE(fio->page, false));
+
+ __submit_bio(fio->sbi, bio, fio->type);
+ return 0;
+@@ -941,7 +939,7 @@ int f2fs_merge_page_bio(struct f2fs_io_info *fio)
+ if (fio->io_wbc)
+ wbc_account_cgroup_owner(fio->io_wbc, fio->page, PAGE_SIZE);
+
+- inc_page_count(fio->sbi, WB_DATA_TYPE(page));
++ inc_page_count(fio->sbi, WB_DATA_TYPE(page, false));
+
+ *fio->last_block = fio->new_blkaddr;
+ *fio->bio = bio;
+@@ -955,6 +953,7 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio)
+ enum page_type btype = PAGE_TYPE_OF_BIO(fio->type);
+ struct f2fs_bio_info *io = sbi->write_io[btype] + fio->temp;
+ struct page *bio_page;
++ enum count_type type;
+
+ f2fs_bug_on(sbi, is_read_io(fio->op));
+
+@@ -984,7 +983,8 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio)
+ /* set submitted = true as a return value */
+ fio->submitted = 1;
+
+- inc_page_count(sbi, WB_DATA_TYPE(bio_page));
++ type = WB_DATA_TYPE(bio_page, fio->compressed_page);
++ inc_page_count(sbi, type);
+
+ if (io->bio &&
+ (!io_is_mergeable(sbi, io->bio, io, fio, io->last_block_in_bio,
+@@ -997,7 +997,8 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio)
+ if (F2FS_IO_ALIGNED(sbi) &&
+ (fio->type == DATA || fio->type == NODE) &&
+ fio->new_blkaddr & F2FS_IO_SIZE_MASK(sbi)) {
+- dec_page_count(sbi, WB_DATA_TYPE(bio_page));
++ dec_page_count(sbi, WB_DATA_TYPE(bio_page,
++ fio->compressed_page));
+ fio->retry = 1;
+ goto skip;
+ }
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 1d78bca5037f4..16dacf811481c 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -1067,7 +1067,8 @@ struct f2fs_sm_info {
+ * f2fs monitors the number of several block types such as on-writeback,
+ * dirty dentry blocks, dirty node blocks, and dirty meta blocks.
+ */
+-#define WB_DATA_TYPE(p) (__is_cp_guaranteed(p) ? F2FS_WB_CP_DATA : F2FS_WB_DATA)
++#define WB_DATA_TYPE(p, f) \
++ (f || f2fs_is_cp_guaranteed(p) ? F2FS_WB_CP_DATA : F2FS_WB_DATA)
+ enum count_type {
+ F2FS_DIRTY_DENTS,
+ F2FS_DIRTY_DATA,
+@@ -3761,6 +3762,7 @@ void f2fs_init_ckpt_req_control(struct f2fs_sb_info *sbi);
+ */
+ int __init f2fs_init_bioset(void);
+ void f2fs_destroy_bioset(void);
++bool f2fs_is_cp_guaranteed(struct page *page);
+ int f2fs_init_bio_entry_cache(void);
+ void f2fs_destroy_bio_entry_cache(void);
+ void f2fs_submit_bio(struct f2fs_sb_info *sbi,
+--
+2.43.0
+
--- /dev/null
+From e5ea2a4ad83a739ca1ac1d169bdc7dff660ecb96 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Mar 2024 11:47:45 +0800
+Subject: f2fs: compress: relocate some judgments in
+ f2fs_reserve_compress_blocks
+
+From: Xiuhong Wang <xiuhong.wang@unisoc.com>
+
+[ Upstream commit b7d797d241c154d73ec5523f87f3b06d4f299da1 ]
+
+The following f2fs_io test will get a "0" result instead of -EINVAL,
+unisoc # ./f2fs_io compress file
+unisoc # ./f2fs_io reserve_cblocks file
+ 0
+it's not reasonable, so the judgement of
+atomic_read(&F2FS_I(inode)->i_compr_blocks) should be placed after
+the judgement of is_inode_flag_set(inode, FI_COMPRESS_RELEASED).
+
+Fixes: c75488fb4d82 ("f2fs: introduce F2FS_IOC_RESERVE_COMPRESS_BLOCKS")
+Signed-off-by: Xiuhong Wang <xiuhong.wang@unisoc.com>
+Signed-off-by: Zhiguo Niu <zhiguo.niu@unisoc.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index c787a3f408ab3..5dbd874ba3d8d 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -3657,9 +3657,6 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
+ if (ret)
+ return ret;
+
+- if (atomic_read(&F2FS_I(inode)->i_compr_blocks))
+- goto out;
+-
+ f2fs_balance_fs(sbi, true);
+
+ inode_lock(inode);
+@@ -3669,6 +3666,9 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
+ goto unlock_inode;
+ }
+
++ if (atomic_read(&F2FS_I(inode)->i_compr_blocks))
++ goto unlock_inode;
++
+ f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+ filemap_invalidate_lock(inode->i_mapping);
+
+@@ -3715,7 +3715,6 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
+ }
+ unlock_inode:
+ inode_unlock(inode);
+-out:
+ mnt_drop_write_file(filp);
+
+ if (ret >= 0) {
+--
+2.43.0
+
--- /dev/null
+From b3aacc819a8bb65f590fdc6fad5618732996d861 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 15:51:57 +0800
+Subject: f2fs: convert to use sbi directly
+
+From: Yangtao Li <frank.li@vivo.com>
+
+[ Upstream commit c3355ea9d82fe6b1a4226c9a7d311f9c5715b456 ]
+
+F2FS_I_SB(inode) is redundant.
+
+Signed-off-by: Yangtao Li <frank.li@vivo.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: b7d797d241c1 ("f2fs: compress: relocate some judgments in f2fs_reserve_compress_blocks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index be4cab941d299..c787a3f408ab3 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -3462,7 +3462,7 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
+ int ret;
+ int writecount;
+
+- if (!f2fs_sb_has_compression(F2FS_I_SB(inode)))
++ if (!f2fs_sb_has_compression(sbi))
+ return -EOPNOTSUPP;
+
+ if (!f2fs_compressed_file(inode))
+@@ -3475,7 +3475,7 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg)
+ if (ret)
+ return ret;
+
+- f2fs_balance_fs(F2FS_I_SB(inode), true);
++ f2fs_balance_fs(sbi, true);
+
+ inode_lock(inode);
+
+@@ -3644,7 +3644,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
+ unsigned int reserved_blocks = 0;
+ int ret;
+
+- if (!f2fs_sb_has_compression(F2FS_I_SB(inode)))
++ if (!f2fs_sb_has_compression(sbi))
+ return -EOPNOTSUPP;
+
+ if (!f2fs_compressed_file(inode))
+@@ -3660,7 +3660,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg)
+ if (atomic_read(&F2FS_I(inode)->i_compr_blocks))
+ goto out;
+
+- f2fs_balance_fs(F2FS_I_SB(inode), true);
++ f2fs_balance_fs(sbi, true);
+
+ inode_lock(inode);
+
+@@ -4070,7 +4070,7 @@ static int f2fs_ioc_decompress_file(struct file *filp, unsigned long arg)
+ if (!f2fs_compressed_file(inode))
+ return -EINVAL;
+
+- f2fs_balance_fs(F2FS_I_SB(inode), true);
++ f2fs_balance_fs(sbi, true);
+
+ file_start_write(filp);
+ inode_lock(inode);
+@@ -4142,7 +4142,7 @@ static int f2fs_ioc_compress_file(struct file *filp, unsigned long arg)
+ if (!f2fs_compressed_file(inode))
+ return -EINVAL;
+
+- f2fs_balance_fs(F2FS_I_SB(inode), true);
++ f2fs_balance_fs(sbi, true);
+
+ file_start_write(filp);
+ inode_lock(inode);
+--
+2.43.0
+
--- /dev/null
+From 2a25d59841c8b855ab7b03960ff7321d3877a2ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 Dec 2023 17:20:36 +0800
+Subject: f2fs: delete obsolete FI_DROP_CACHE
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit bb6e1c8fa5b9b95bbb8e39b6105f8f6550e070fc ]
+
+FI_DROP_CACHE was introduced in commit 1e84371ffeef ("f2fs: change
+atomic and volatile write policies") for volatile write feature,
+after commit 7bc155fec5b3 ("f2fs: kill volatile write support"),
+we won't support volatile write, let's delete related codes.
+
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: 54607494875e ("f2fs: compress: fix to avoid inconsistence bewteen i_blocks and dnode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/data.c | 3 ---
+ fs/f2fs/f2fs.h | 6 ------
+ 2 files changed, 9 deletions(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 95e737fc75ef0..a5d0d0b892875 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -2817,9 +2817,6 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
+
+ zero_user_segment(page, offset, PAGE_SIZE);
+ write:
+- if (f2fs_is_drop_cache(inode))
+- goto out;
+-
+ /* Dentry/quota blocks are controlled by checkpoint */
+ if (S_ISDIR(inode->i_mode) || quota_inode) {
+ /*
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 2364b6f7500b2..0f7193a0ab422 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -764,7 +764,6 @@ enum {
+ FI_UPDATE_WRITE, /* inode has in-place-update data */
+ FI_NEED_IPU, /* used for ipu per file */
+ FI_ATOMIC_FILE, /* indicate atomic file */
+- FI_DROP_CACHE, /* drop dirty page cache */
+ FI_DATA_EXIST, /* indicate data exists */
+ FI_INLINE_DOTS, /* indicate inline dot dentries */
+ FI_SKIP_WRITES, /* should skip data page writeback */
+@@ -3247,11 +3246,6 @@ static inline bool f2fs_is_cow_file(struct inode *inode)
+ return is_inode_flag_set(inode, FI_COW_FILE);
+ }
+
+-static inline bool f2fs_is_drop_cache(struct inode *inode)
+-{
+- return is_inode_flag_set(inode, FI_DROP_CACHE);
+-}
+-
+ static inline void *inline_data_addr(struct inode *inode, struct page *page)
+ {
+ struct f2fs_inode *ri = F2FS_INODE(page);
+--
+2.43.0
+
--- /dev/null
+From 9ed0cf2a274523f453cce4ad3375722dca0f4ba9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 Dec 2023 17:20:35 +0800
+Subject: f2fs: delete obsolete FI_FIRST_BLOCK_WRITTEN
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit a53936361330e4c55c0654605178281387d9c761 ]
+
+Commit 3c6c2bebef79 ("f2fs: avoid punch_hole overhead when releasing
+volatile data") introduced FI_FIRST_BLOCK_WRITTEN as below reason:
+
+This patch is to avoid some punch_hole overhead when releasing volatile
+data. If volatile data was not written yet, we just can make the first
+page as zero.
+
+After commit 7bc155fec5b3 ("f2fs: kill volatile write support"), we
+won't support volatile write, but it missed to remove obsolete
+FI_FIRST_BLOCK_WRITTEN, delete it in this patch.
+
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: 54607494875e ("f2fs: compress: fix to avoid inconsistence bewteen i_blocks and dnode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/compress.c | 2 --
+ fs/f2fs/data.c | 2 --
+ fs/f2fs/f2fs.h | 6 ------
+ fs/f2fs/file.c | 3 ---
+ fs/f2fs/gc.c | 2 --
+ fs/f2fs/inode.c | 25 -------------------------
+ 6 files changed, 40 deletions(-)
+
+diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
+index 553950962842a..5973fda2349c7 100644
+--- a/fs/f2fs/compress.c
++++ b/fs/f2fs/compress.c
+@@ -1388,8 +1388,6 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
+ add_compr_block_stat(inode, cc->valid_nr_cpages);
+
+ set_inode_flag(cc->inode, FI_APPEND_WRITE);
+- if (cc->cluster_idx == 0)
+- set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN);
+
+ f2fs_put_dnode(&dn);
+ if (quota_inode)
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 77b825fdeec85..95e737fc75ef0 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -2739,8 +2739,6 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
+ f2fs_outplace_write_data(&dn, fio);
+ trace_f2fs_do_write_data_page(page, OPU);
+ set_inode_flag(inode, FI_APPEND_WRITE);
+- if (page->index == 0)
+- set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN);
+ out_writepage:
+ f2fs_put_dnode(&dn);
+ out:
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 16dacf811481c..2364b6f7500b2 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -764,7 +764,6 @@ enum {
+ FI_UPDATE_WRITE, /* inode has in-place-update data */
+ FI_NEED_IPU, /* used for ipu per file */
+ FI_ATOMIC_FILE, /* indicate atomic file */
+- FI_FIRST_BLOCK_WRITTEN, /* indicate #0 data block was written */
+ FI_DROP_CACHE, /* drop dirty page cache */
+ FI_DATA_EXIST, /* indicate data exists */
+ FI_INLINE_DOTS, /* indicate inline dot dentries */
+@@ -3248,11 +3247,6 @@ static inline bool f2fs_is_cow_file(struct inode *inode)
+ return is_inode_flag_set(inode, FI_COW_FILE);
+ }
+
+-static inline bool f2fs_is_first_block_written(struct inode *inode)
+-{
+- return is_inode_flag_set(inode, FI_FIRST_BLOCK_WRITTEN);
+-}
+-
+ static inline bool f2fs_is_drop_cache(struct inode *inode)
+ {
+ return is_inode_flag_set(inode, FI_DROP_CACHE);
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 6c9f03e3be8e9..4d634b5b6011f 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -602,9 +602,6 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count)
+ valid_blocks++;
+ }
+
+- if (dn->ofs_in_node == 0 && IS_INODE(dn->node_page))
+- clear_inode_flag(dn->inode, FI_FIRST_BLOCK_WRITTEN);
+-
+ f2fs_invalidate_blocks(sbi, blkaddr);
+
+ if (!released || blkaddr != COMPRESS_ADDR)
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 8161355658562..d4662ccb94c8f 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1410,8 +1410,6 @@ static int move_data_block(struct inode *inode, block_t bidx,
+
+ f2fs_update_data_blkaddr(&dn, newaddr);
+ set_inode_flag(inode, FI_APPEND_WRITE);
+- if (page->index == 0)
+- set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN);
+ put_page_out:
+ f2fs_put_page(fio.encrypted_page, 1);
+ recover_block:
+diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
+index 0010579f17368..f0f2584fed66e 100644
+--- a/fs/f2fs/inode.c
++++ b/fs/f2fs/inode.c
+@@ -74,20 +74,6 @@ static void __get_inode_rdev(struct inode *inode, struct f2fs_inode *ri)
+ }
+ }
+
+-static int __written_first_block(struct f2fs_sb_info *sbi,
+- struct f2fs_inode *ri)
+-{
+- block_t addr = le32_to_cpu(ri->i_addr[offset_in_addr(ri)]);
+-
+- if (!__is_valid_data_blkaddr(addr))
+- return 1;
+- if (!f2fs_is_valid_blkaddr(sbi, addr, DATA_GENERIC_ENHANCE)) {
+- f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
+- return -EFSCORRUPTED;
+- }
+- return 0;
+-}
+-
+ static void __set_inode_rdev(struct inode *inode, struct f2fs_inode *ri)
+ {
+ int extra_size = get_extra_isize(inode);
+@@ -336,7 +322,6 @@ static int do_read_inode(struct inode *inode)
+ struct page *node_page;
+ struct f2fs_inode *ri;
+ projid_t i_projid;
+- int err;
+
+ /* Check if ino is within scope */
+ if (f2fs_check_nid_range(sbi, inode->i_ino))
+@@ -417,16 +402,6 @@ static int do_read_inode(struct inode *inode)
+ /* get rdev by using inline_info */
+ __get_inode_rdev(inode, ri);
+
+- if (S_ISREG(inode->i_mode)) {
+- err = __written_first_block(sbi, ri);
+- if (err < 0) {
+- f2fs_put_page(node_page, 1);
+- return err;
+- }
+- if (!err)
+- set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN);
+- }
+-
+ if (!f2fs_need_inode_block_update(sbi, inode->i_ino))
+ fi->last_disk_size = inode->i_size;
+
+--
+2.43.0
+
--- /dev/null
+From b10fc43f2822a0fe62d6ce2b130db34c57e1c1ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jan 2024 22:49:15 +0800
+Subject: f2fs: fix to avoid potential panic during recovery
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 21ec68234826b1b54ab980a8df6e33c74cfbee58 ]
+
+During recovery, if FAULT_BLOCK is on, it is possible that
+f2fs_reserve_new_block() will return -ENOSPC during recovery,
+then it may trigger panic.
+
+Also, if fault injection rate is 1 and only FAULT_BLOCK fault
+type is on, it may encounter deadloop in loop of block reservation.
+
+Let's change as below to fix these issues:
+- remove bug_on() to avoid panic.
+- limit the loop count of block reservation to avoid potential
+deadloop.
+
+Fixes: 956fa1ddc132 ("f2fs: fix to check return value of f2fs_reserve_new_block()")
+Reported-by: Zhiguo Niu <zhiguo.niu@unisoc.com>
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/f2fs.h | 5 +++++
+ fs/f2fs/recovery.c | 33 ++++++++++++++++-----------------
+ 2 files changed, 21 insertions(+), 17 deletions(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index a81091a5e282d..f5d69893d2d92 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -74,6 +74,11 @@ struct f2fs_fault_info {
+
+ extern const char *f2fs_fault_name[FAULT_MAX];
+ #define IS_FAULT_SET(fi, type) ((fi)->inject_type & BIT(type))
++
++/* maximum retry count for injected failure */
++#define DEFAULT_FAILURE_RETRY_COUNT 8
++#else
++#define DEFAULT_FAILURE_RETRY_COUNT 1
+ #endif
+
+ /*
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index 53a6487f91e44..f5efc37a2b513 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -582,6 +582,19 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
+ return 0;
+ }
+
++static int f2fs_reserve_new_block_retry(struct dnode_of_data *dn)
++{
++ int i, err = 0;
++
++ for (i = DEFAULT_FAILURE_RETRY_COUNT; i > 0; i--) {
++ err = f2fs_reserve_new_block(dn);
++ if (!err)
++ break;
++ }
++
++ return err;
++}
++
+ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
+ struct page *page)
+ {
+@@ -683,14 +696,8 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
+ */
+ if (dest == NEW_ADDR) {
+ f2fs_truncate_data_blocks_range(&dn, 1);
+- do {
+- err = f2fs_reserve_new_block(&dn);
+- if (err == -ENOSPC) {
+- f2fs_bug_on(sbi, 1);
+- break;
+- }
+- } while (err &&
+- IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION));
++
++ err = f2fs_reserve_new_block_retry(&dn);
+ if (err)
+ goto err;
+ continue;
+@@ -698,16 +705,8 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
+
+ /* dest is valid block, try to recover from src to dest */
+ if (f2fs_is_valid_blkaddr(sbi, dest, META_POR)) {
+-
+ if (src == NULL_ADDR) {
+- do {
+- err = f2fs_reserve_new_block(&dn);
+- if (err == -ENOSPC) {
+- f2fs_bug_on(sbi, 1);
+- break;
+- }
+- } while (err &&
+- IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION));
++ err = f2fs_reserve_new_block_retry(&dn);
+ if (err)
+ goto err;
+ }
+--
+2.43.0
+
--- /dev/null
+From f80eb116ccef070a9c6e11319977aea13737fee5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 Dec 2023 17:20:37 +0800
+Subject: f2fs: introduce get_dnode_addr() to clean up codes
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 2020cd48e41cb8470bb1ca0835033d13d3178425 ]
+
+Just cleanup, no logic changes.
+
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: 54607494875e ("f2fs: compress: fix to avoid inconsistence bewteen i_blocks and dnode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/data.c | 11 ++---------
+ fs/f2fs/f2fs.h | 18 +++++++++++++++---
+ fs/f2fs/file.c | 8 +-------
+ fs/f2fs/inode.c | 32 ++++++++++++++------------------
+ 4 files changed, 32 insertions(+), 37 deletions(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index a5d0d0b892875..65b69d38f332c 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -1105,16 +1105,9 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page,
+
+ static void __set_data_blkaddr(struct dnode_of_data *dn)
+ {
+- struct f2fs_node *rn = F2FS_NODE(dn->node_page);
+- __le32 *addr_array;
+- int base = 0;
++ __le32 *addr = get_dnode_addr(dn->inode, dn->node_page);
+
+- if (IS_INODE(dn->node_page) && f2fs_has_extra_attr(dn->inode))
+- base = get_extra_isize(dn->inode);
+-
+- /* Get physical address of data block */
+- addr_array = blkaddr_in_node(rn);
+- addr_array[base + dn->ofs_in_node] = cpu_to_le32(dn->data_blkaddr);
++ addr[dn->ofs_in_node] = cpu_to_le32(dn->data_blkaddr);
+ }
+
+ /*
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 0f7193a0ab422..108ba10679da2 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -3246,12 +3246,13 @@ static inline bool f2fs_is_cow_file(struct inode *inode)
+ return is_inode_flag_set(inode, FI_COW_FILE);
+ }
+
++static inline __le32 *get_dnode_addr(struct inode *inode,
++ struct page *node_page);
+ static inline void *inline_data_addr(struct inode *inode, struct page *page)
+ {
+- struct f2fs_inode *ri = F2FS_INODE(page);
+- int extra_size = get_extra_isize(inode);
++ __le32 *addr = get_dnode_addr(inode, page);
+
+- return (void *)&(ri->i_addr[extra_size + DEF_INLINE_RESERVED_SIZE]);
++ return (void *)(addr + DEF_INLINE_RESERVED_SIZE);
+ }
+
+ static inline int f2fs_has_inline_dentry(struct inode *inode)
+@@ -3386,6 +3387,17 @@ static inline int get_inline_xattr_addrs(struct inode *inode)
+ return F2FS_I(inode)->i_inline_xattr_size;
+ }
+
++static inline __le32 *get_dnode_addr(struct inode *inode,
++ struct page *node_page)
++{
++ int base = 0;
++
++ if (IS_INODE(node_page) && f2fs_has_extra_attr(inode))
++ base = get_extra_isize(inode);
++
++ return blkaddr_in_node(F2FS_NODE(node_page)) + base;
++}
++
+ #define f2fs_get_inode_mode(i) \
+ ((is_inode_flag_set(i, FI_ACL_MODE)) ? \
+ (F2FS_I(i)->i_acl_mode) : ((i)->i_mode))
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 4d634b5b6011f..9a81d51ddf9e2 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -560,20 +560,14 @@ static int f2fs_file_open(struct inode *inode, struct file *filp)
+ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count)
+ {
+ struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
+- struct f2fs_node *raw_node;
+ int nr_free = 0, ofs = dn->ofs_in_node, len = count;
+ __le32 *addr;
+- int base = 0;
+ bool compressed_cluster = false;
+ int cluster_index = 0, valid_blocks = 0;
+ int cluster_size = F2FS_I(dn->inode)->i_cluster_size;
+ bool released = !atomic_read(&F2FS_I(dn->inode)->i_compr_blocks);
+
+- if (IS_INODE(dn->node_page) && f2fs_has_extra_attr(dn->inode))
+- base = get_extra_isize(dn->inode);
+-
+- raw_node = F2FS_NODE(dn->node_page);
+- addr = blkaddr_in_node(raw_node) + base + ofs;
++ addr = get_dnode_addr(dn->inode, dn->node_page) + ofs;
+
+ /* Assumption: truncateion starts with cluster */
+ for (; count > 0; count--, addr++, dn->ofs_in_node++, cluster_index++) {
+diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
+index f0f2584fed66e..869bb6ec107cc 100644
+--- a/fs/f2fs/inode.c
++++ b/fs/f2fs/inode.c
+@@ -59,35 +59,31 @@ void f2fs_set_inode_flags(struct inode *inode)
+ S_ENCRYPTED|S_VERITY|S_CASEFOLD);
+ }
+
+-static void __get_inode_rdev(struct inode *inode, struct f2fs_inode *ri)
++static void __get_inode_rdev(struct inode *inode, struct page *node_page)
+ {
+- int extra_size = get_extra_isize(inode);
++ __le32 *addr = get_dnode_addr(inode, node_page);
+
+ if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||
+ S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
+- if (ri->i_addr[extra_size])
+- inode->i_rdev = old_decode_dev(
+- le32_to_cpu(ri->i_addr[extra_size]));
++ if (addr[0])
++ inode->i_rdev = old_decode_dev(le32_to_cpu(addr[0]));
+ else
+- inode->i_rdev = new_decode_dev(
+- le32_to_cpu(ri->i_addr[extra_size + 1]));
++ inode->i_rdev = new_decode_dev(le32_to_cpu(addr[1]));
+ }
+ }
+
+-static void __set_inode_rdev(struct inode *inode, struct f2fs_inode *ri)
++static void __set_inode_rdev(struct inode *inode, struct page *node_page)
+ {
+- int extra_size = get_extra_isize(inode);
++ __le32 *addr = get_dnode_addr(inode, node_page);
+
+ if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
+ if (old_valid_dev(inode->i_rdev)) {
+- ri->i_addr[extra_size] =
+- cpu_to_le32(old_encode_dev(inode->i_rdev));
+- ri->i_addr[extra_size + 1] = 0;
++ addr[0] = cpu_to_le32(old_encode_dev(inode->i_rdev));
++ addr[1] = 0;
+ } else {
+- ri->i_addr[extra_size] = 0;
+- ri->i_addr[extra_size + 1] =
+- cpu_to_le32(new_encode_dev(inode->i_rdev));
+- ri->i_addr[extra_size + 2] = 0;
++ addr[0] = 0;
++ addr[1] = cpu_to_le32(new_encode_dev(inode->i_rdev));
++ addr[2] = 0;
+ }
+ }
+ }
+@@ -400,7 +396,7 @@ static int do_read_inode(struct inode *inode)
+ }
+
+ /* get rdev by using inline_info */
+- __get_inode_rdev(inode, ri);
++ __get_inode_rdev(inode, node_page);
+
+ if (!f2fs_need_inode_block_update(sbi, inode->i_ino))
+ fi->last_disk_size = inode->i_size;
+@@ -672,7 +668,7 @@ void f2fs_update_inode(struct inode *inode, struct page *node_page)
+ }
+ }
+
+- __set_inode_rdev(inode, ri);
++ __set_inode_rdev(inode, node_page);
+
+ /* deleted inode */
+ if (inode->i_nlink == 0)
+--
+2.43.0
+
--- /dev/null
+From 4fcdca275cf8383e845dba967d7c6ed8a1a125c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 15:04:56 +0800
+Subject: f2fs: reduce stack memory cost by using bitfield in struct
+ f2fs_io_info
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 2eae077e6e46f9046d383631145750e043820dce ]
+
+This patch tries to use bitfield in struct f2fs_io_info to improve
+memory usage.
+
+struct f2fs_io_info {
+...
+ unsigned int need_lock:8; /* indicate we need to lock cp_rwsem */
+ unsigned int version:8; /* version of the node */
+ unsigned int submitted:1; /* indicate IO submission */
+ unsigned int in_list:1; /* indicate fio is in io_list */
+ unsigned int is_por:1; /* indicate IO is from recovery or not */
+ unsigned int retry:1; /* need to reallocate block address */
+ unsigned int encrypted:1; /* indicate file is encrypted */
+ unsigned int post_read:1; /* require post read */
+...
+};
+
+After this patch, size of struct f2fs_io_info reduces from 136 to 120.
+
+[Nathan: fix a compile warning (single-bit-bitfield-constant-conversion)]
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: 8a430dd49e9c ("f2fs: compress: fix to guarantee persisting compressed blocks by CP")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/checkpoint.c | 6 +++---
+ fs/f2fs/compress.c | 5 +++--
+ fs/f2fs/data.c | 10 +++++-----
+ fs/f2fs/f2fs.h | 18 +++++++++---------
+ fs/f2fs/gc.c | 8 ++++----
+ fs/f2fs/node.c | 2 +-
+ fs/f2fs/segment.c | 6 +++---
+ 7 files changed, 28 insertions(+), 27 deletions(-)
+
+diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
+index eb4d69f53337f..3ec203bbd5593 100644
+--- a/fs/f2fs/checkpoint.c
++++ b/fs/f2fs/checkpoint.c
+@@ -70,7 +70,7 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
+ .old_blkaddr = index,
+ .new_blkaddr = index,
+ .encrypted_page = NULL,
+- .is_por = !is_meta,
++ .is_por = !is_meta ? 1 : 0,
+ };
+ int err;
+
+@@ -234,8 +234,8 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
+ .op = REQ_OP_READ,
+ .op_flags = sync ? (REQ_META | REQ_PRIO) : REQ_RAHEAD,
+ .encrypted_page = NULL,
+- .in_list = false,
+- .is_por = (type == META_POR),
++ .in_list = 0,
++ .is_por = (type == META_POR) ? 1 : 0,
+ };
+ struct blk_plug plug;
+ int err;
+diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
+index 967262c37da52..7d85db7208e14 100644
+--- a/fs/f2fs/compress.c
++++ b/fs/f2fs/compress.c
+@@ -1249,10 +1249,11 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc,
+ .page = NULL,
+ .encrypted_page = NULL,
+ .compressed_page = NULL,
+- .submitted = false,
++ .submitted = 0,
+ .io_type = io_type,
+ .io_wbc = wbc,
+- .encrypted = fscrypt_inode_uses_fs_layer_crypto(cc->inode),
++ .encrypted = fscrypt_inode_uses_fs_layer_crypto(cc->inode) ?
++ 1 : 0,
+ };
+ struct dnode_of_data dn;
+ struct node_info ni;
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 8b561af379743..7b3eb192f9c03 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -982,7 +982,7 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio)
+ bio_page = fio->page;
+
+ /* set submitted = true as a return value */
+- fio->submitted = true;
++ fio->submitted = 1;
+
+ inc_page_count(sbi, WB_DATA_TYPE(bio_page));
+
+@@ -998,7 +998,7 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio)
+ (fio->type == DATA || fio->type == NODE) &&
+ fio->new_blkaddr & F2FS_IO_SIZE_MASK(sbi)) {
+ dec_page_count(sbi, WB_DATA_TYPE(bio_page));
+- fio->retry = true;
++ fio->retry = 1;
+ goto skip;
+ }
+ io->bio = __bio_alloc(fio, BIO_MAX_VECS);
+@@ -2776,10 +2776,10 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
+ .old_blkaddr = NULL_ADDR,
+ .page = page,
+ .encrypted_page = NULL,
+- .submitted = false,
++ .submitted = 0,
+ .compr_blocks = compr_blocks,
+ .need_lock = LOCK_RETRY,
+- .post_read = f2fs_post_read_required(inode),
++ .post_read = f2fs_post_read_required(inode) ? 1 : 0,
+ .io_type = io_type,
+ .io_wbc = wbc,
+ .bio = bio,
+@@ -2902,7 +2902,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
+ }
+
+ if (submitted)
+- *submitted = fio.submitted ? 1 : 0;
++ *submitted = fio.submitted;
+
+ return 0;
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index e5a9498b89c06..1d78bca5037f4 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -1183,19 +1183,19 @@ struct f2fs_io_info {
+ struct page *encrypted_page; /* encrypted page */
+ struct page *compressed_page; /* compressed page */
+ struct list_head list; /* serialize IOs */
+- bool submitted; /* indicate IO submission */
+- int need_lock; /* indicate we need to lock cp_rwsem */
+- bool in_list; /* indicate fio is in io_list */
+- bool is_por; /* indicate IO is from recovery or not */
+- bool retry; /* need to reallocate block address */
+- int compr_blocks; /* # of compressed block addresses */
+- bool encrypted; /* indicate file is encrypted */
+- bool post_read; /* require post read */
++ unsigned int compr_blocks; /* # of compressed block addresses */
++ unsigned int need_lock:8; /* indicate we need to lock cp_rwsem */
++ unsigned int version:8; /* version of the node */
++ unsigned int submitted:1; /* indicate IO submission */
++ unsigned int in_list:1; /* indicate fio is in io_list */
++ unsigned int is_por:1; /* indicate IO is from recovery or not */
++ unsigned int retry:1; /* need to reallocate block address */
++ unsigned int encrypted:1; /* indicate file is encrypted */
++ unsigned int post_read:1; /* require post read */
+ enum iostat_type io_type; /* io type */
+ struct writeback_control *io_wbc; /* writeback control */
+ struct bio **bio; /* bio for ipu */
+ sector_t *last_block; /* last block number in bio */
+- unsigned char version; /* version of the node */
+ };
+
+ struct bio_entry {
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index ec7212f7a9b73..8161355658562 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1187,8 +1187,8 @@ static int ra_data_block(struct inode *inode, pgoff_t index)
+ .op = REQ_OP_READ,
+ .op_flags = 0,
+ .encrypted_page = NULL,
+- .in_list = false,
+- .retry = false,
++ .in_list = 0,
++ .retry = 0,
+ };
+ int err;
+
+@@ -1276,8 +1276,8 @@ static int move_data_block(struct inode *inode, block_t bidx,
+ .op = REQ_OP_READ,
+ .op_flags = 0,
+ .encrypted_page = NULL,
+- .in_list = false,
+- .retry = false,
++ .in_list = 0,
++ .retry = 0,
+ };
+ struct dnode_of_data dn;
+ struct f2fs_summary sum;
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index c6d0e07096326..5db6740d31364 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -1587,7 +1587,7 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted,
+ .op_flags = wbc_to_write_flags(wbc),
+ .page = page,
+ .encrypted_page = NULL,
+- .submitted = false,
++ .submitted = 0,
+ .io_type = io_type,
+ .io_wbc = wbc,
+ };
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 16bf9d5c8d4f9..a3dabec1f216a 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -3312,10 +3312,10 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
+ struct f2fs_bio_info *io;
+
+ if (F2FS_IO_ALIGNED(sbi))
+- fio->retry = false;
++ fio->retry = 0;
+
+ INIT_LIST_HEAD(&fio->list);
+- fio->in_list = true;
++ fio->in_list = 1;
+ io = sbi->write_io[fio->type] + fio->temp;
+ spin_lock(&io->io_lock);
+ list_add_tail(&fio->list, &io->io_list);
+@@ -3396,7 +3396,7 @@ void f2fs_do_write_meta_page(struct f2fs_sb_info *sbi, struct page *page,
+ .new_blkaddr = page->index,
+ .page = page,
+ .encrypted_page = NULL,
+- .in_list = false,
++ .in_list = 0,
+ };
+
+ if (unlikely(page->index >= MAIN_BLKADDR(sbi)))
+--
+2.43.0
+
--- /dev/null
+From 342cac122e6b3cf8656e7967d7ae5c9a036b9842 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Feb 2024 15:35:38 +0800
+Subject: f2fs: ro: compress: fix to avoid caching unaligned extent
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 4b99ecd304290c4ef55666a62c89dfb2dbf0b2cd ]
+
+Mapping info from dump.f2fs:
+i_addr[0x2d] cluster flag [0xfffffffe : 4294967294]
+i_addr[0x2e] [0x 10428 : 66600]
+i_addr[0x2f] [0x 10429 : 66601]
+i_addr[0x30] [0x 1042a : 66602]
+
+f2fs_io fiemap 37 1 /mnt/f2fs/disk-58390c8c.raw
+
+Previsouly, it missed to align fofs and ofs_in_node to cluster_size,
+result in adding incorrect read extent cache, fix it.
+
+Before:
+f2fs_update_read_extent_tree_range: dev = (253,48), ino = 5, pgofs = 37, len = 4, blkaddr = 66600, c_len = 3
+
+After:
+f2fs_update_read_extent_tree_range: dev = (253,48), ino = 5, pgofs = 36, len = 4, blkaddr = 66600, c_len = 3
+
+Fixes: 94afd6d6e525 ("f2fs: extent cache: support unaligned extent")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/compress.c | 10 ++++++----
+ fs/f2fs/f2fs.h | 6 ++++--
+ fs/f2fs/node.c | 20 ++++++++++++++------
+ 3 files changed, 24 insertions(+), 12 deletions(-)
+
+diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
+index 5973fda2349c7..df6dfd7de6d0d 100644
+--- a/fs/f2fs/compress.c
++++ b/fs/f2fs/compress.c
+@@ -1843,16 +1843,18 @@ void f2fs_put_page_dic(struct page *page, bool in_task)
+ * check whether cluster blocks are contiguous, and add extent cache entry
+ * only if cluster blocks are logically and physically contiguous.
+ */
+-unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn)
++unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn,
++ unsigned int ofs_in_node)
+ {
+- bool compressed = f2fs_data_blkaddr(dn) == COMPRESS_ADDR;
++ bool compressed = data_blkaddr(dn->inode, dn->node_page,
++ ofs_in_node) == COMPRESS_ADDR;
+ int i = compressed ? 1 : 0;
+ block_t first_blkaddr = data_blkaddr(dn->inode, dn->node_page,
+- dn->ofs_in_node + i);
++ ofs_in_node + i);
+
+ for (i += 1; i < F2FS_I(dn->inode)->i_cluster_size; i++) {
+ block_t blkaddr = data_blkaddr(dn->inode, dn->node_page,
+- dn->ofs_in_node + i);
++ ofs_in_node + i);
+
+ if (!__is_valid_data_blkaddr(blkaddr))
+ break;
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index f5d69893d2d92..5ae1c4aa3ae92 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -4258,7 +4258,8 @@ struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc);
+ void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed,
+ bool in_task);
+ void f2fs_put_page_dic(struct page *page, bool in_task);
+-unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn);
++unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn,
++ unsigned int ofs_in_node);
+ int f2fs_init_compress_ctx(struct compress_ctx *cc);
+ void f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse);
+ void f2fs_init_compress_info(struct f2fs_sb_info *sbi);
+@@ -4315,7 +4316,8 @@ static inline void f2fs_put_page_dic(struct page *page, bool in_task)
+ {
+ WARN_ON_ONCE(1);
+ }
+-static inline unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn) { return 0; }
++static inline unsigned int f2fs_cluster_blocks_are_contiguous(
++ struct dnode_of_data *dn, unsigned int ofs_in_node) { return 0; }
+ static inline bool f2fs_sanity_check_cluster(struct dnode_of_data *dn) { return false; }
+ static inline int f2fs_init_compress_inode(struct f2fs_sb_info *sbi) { return 0; }
+ static inline void f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi) { }
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index 5db6740d31364..fcf22a50ff5db 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -850,21 +850,29 @@ int f2fs_get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode)
+
+ if (is_inode_flag_set(dn->inode, FI_COMPRESSED_FILE) &&
+ f2fs_sb_has_readonly(sbi)) {
+- unsigned int c_len = f2fs_cluster_blocks_are_contiguous(dn);
++ unsigned int cluster_size = F2FS_I(dn->inode)->i_cluster_size;
++ unsigned int ofs_in_node = dn->ofs_in_node;
++ pgoff_t fofs = index;
++ unsigned int c_len;
+ block_t blkaddr;
+
++ /* should align fofs and ofs_in_node to cluster_size */
++ if (fofs % cluster_size) {
++ fofs = round_down(fofs, cluster_size);
++ ofs_in_node = round_down(ofs_in_node, cluster_size);
++ }
++
++ c_len = f2fs_cluster_blocks_are_contiguous(dn, ofs_in_node);
+ if (!c_len)
+ goto out;
+
+- blkaddr = f2fs_data_blkaddr(dn);
++ blkaddr = data_blkaddr(dn->inode, dn->node_page, ofs_in_node);
+ if (blkaddr == COMPRESS_ADDR)
+ blkaddr = data_blkaddr(dn->inode, dn->node_page,
+- dn->ofs_in_node + 1);
++ ofs_in_node + 1);
+
+ f2fs_update_read_extent_tree_range_compressed(dn->inode,
+- index, blkaddr,
+- F2FS_I(dn->inode)->i_cluster_size,
+- c_len);
++ fofs, blkaddr, cluster_size, c_len);
+ }
+ out:
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From f165e967a2ca586c503ae467688105382bad8998 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Nov 2022 10:15:18 +0100
+Subject: f2fs: simplify __allocate_data_block
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 3cf684f2f8e0229714fb6d051508b42d3320e78f ]
+
+Just use a simple if block for the conditional call to
+inc_valid_block_count.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: 54607494875e ("f2fs: compress: fix to avoid inconsistence bewteen i_blocks and dnode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/data.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 3f0ba71451c27..77b825fdeec85 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -1420,13 +1420,12 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
+ return err;
+
+ dn->data_blkaddr = f2fs_data_blkaddr(dn);
+- if (dn->data_blkaddr != NULL_ADDR)
+- goto alloc;
+-
+- if (unlikely((err = inc_valid_block_count(sbi, dn->inode, &count))))
+- return err;
++ if (dn->data_blkaddr == NULL_ADDR) {
++ err = inc_valid_block_count(sbi, dn->inode, &count);
++ if (unlikely(err))
++ return err;
++ }
+
+-alloc:
+ set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
+ old_blkaddr = dn->data_blkaddr;
+ f2fs_allocate_data_block(sbi, NULL, old_blkaddr, &dn->data_blkaddr,
+--
+2.43.0
+
--- /dev/null
+From a4b568ff058bc90aa7edaab77c1d747bf2a11f17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 Dec 2023 17:20:38 +0800
+Subject: f2fs: update blkaddr in __set_data_blkaddr() for cleanup
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 59d0d4c3eae0f3dd8886ed59f89f21fa09e324f5 ]
+
+This patch allows caller to pass blkaddr to f2fs_set_data_blkaddr()
+and let __set_data_blkaddr() inside f2fs_set_data_blkaddr() to update
+dn->data_blkaddr w/ last value of blkaddr.
+
+Just cleanup, no logic changes.
+
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: 54607494875e ("f2fs: compress: fix to avoid inconsistence bewteen i_blocks and dnode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/data.c | 13 ++++++-------
+ fs/f2fs/f2fs.h | 2 +-
+ fs/f2fs/file.c | 12 ++++--------
+ 3 files changed, 11 insertions(+), 16 deletions(-)
+
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 65b69d38f332c..1aa7d443cf364 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -1103,10 +1103,11 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page,
+ return 0;
+ }
+
+-static void __set_data_blkaddr(struct dnode_of_data *dn)
++static void __set_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr)
+ {
+ __le32 *addr = get_dnode_addr(dn->inode, dn->node_page);
+
++ dn->data_blkaddr = blkaddr;
+ addr[dn->ofs_in_node] = cpu_to_le32(dn->data_blkaddr);
+ }
+
+@@ -1116,18 +1117,17 @@ static void __set_data_blkaddr(struct dnode_of_data *dn)
+ * ->node_page
+ * update block addresses in the node page
+ */
+-void f2fs_set_data_blkaddr(struct dnode_of_data *dn)
++void f2fs_set_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr)
+ {
+ f2fs_wait_on_page_writeback(dn->node_page, NODE, true, true);
+- __set_data_blkaddr(dn);
++ __set_data_blkaddr(dn, blkaddr);
+ if (set_page_dirty(dn->node_page))
+ dn->node_changed = true;
+ }
+
+ void f2fs_update_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr)
+ {
+- dn->data_blkaddr = blkaddr;
+- f2fs_set_data_blkaddr(dn);
++ f2fs_set_data_blkaddr(dn, blkaddr);
+ f2fs_update_read_extent_cache(dn);
+ }
+
+@@ -1154,8 +1154,7 @@ int f2fs_reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count)
+ block_t blkaddr = f2fs_data_blkaddr(dn);
+
+ if (blkaddr == NULL_ADDR) {
+- dn->data_blkaddr = NEW_ADDR;
+- __set_data_blkaddr(dn);
++ __set_data_blkaddr(dn, NEW_ADDR);
+ count--;
+ }
+ }
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 108ba10679da2..7f34c7d0d156e 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -3781,7 +3781,7 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio);
+ struct block_device *f2fs_target_device(struct f2fs_sb_info *sbi,
+ block_t blk_addr, sector_t *sector);
+ int f2fs_target_device_index(struct f2fs_sb_info *sbi, block_t blkaddr);
+-void f2fs_set_data_blkaddr(struct dnode_of_data *dn);
++void f2fs_set_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr);
+ void f2fs_update_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr);
+ int f2fs_reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count);
+ int f2fs_reserve_new_block(struct dnode_of_data *dn);
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 9a81d51ddf9e2..aa3ded9825f0c 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -585,8 +585,7 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count)
+ if (blkaddr == NULL_ADDR)
+ continue;
+
+- dn->data_blkaddr = NULL_ADDR;
+- f2fs_set_data_blkaddr(dn);
++ f2fs_set_data_blkaddr(dn, NULL_ADDR);
+
+ if (__is_valid_data_blkaddr(blkaddr)) {
+ if (!f2fs_is_valid_blkaddr(sbi, blkaddr,
+@@ -1488,8 +1487,7 @@ static int f2fs_do_zero_range(struct dnode_of_data *dn, pgoff_t start,
+ }
+
+ f2fs_invalidate_blocks(sbi, dn->data_blkaddr);
+- dn->data_blkaddr = NEW_ADDR;
+- f2fs_set_data_blkaddr(dn);
++ f2fs_set_data_blkaddr(dn, NEW_ADDR);
+ }
+
+ f2fs_update_read_extent_cache_range(dn, start, 0, index - start);
+@@ -3440,8 +3438,7 @@ static int release_compress_blocks(struct dnode_of_data *dn, pgoff_t count)
+ if (blkaddr != NEW_ADDR)
+ continue;
+
+- dn->data_blkaddr = NULL_ADDR;
+- f2fs_set_data_blkaddr(dn);
++ f2fs_set_data_blkaddr(dn, NULL_ADDR);
+ }
+
+ f2fs_i_compr_blocks_update(dn->inode, compr_blocks, false);
+@@ -3611,8 +3608,7 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count)
+ continue;
+ }
+
+- dn->data_blkaddr = NEW_ADDR;
+- f2fs_set_data_blkaddr(dn);
++ f2fs_set_data_blkaddr(dn, NEW_ADDR);
+ }
+
+ reserved = cluster_size - compr_blocks;
+--
+2.43.0
+
--- /dev/null
+From 7d334d5d3ac75df59fb330491513b67c20228211 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Jan 2024 12:23:25 +0000
+Subject: firmware: arm_scmi: Fix double free in SMC transport cleanup path
+
+From: Andre Przywara <andre.przywara@arm.com>
+
+[ Upstream commit f1d71576d2c9ec8fdb822173fa7f3de79475e9bd ]
+
+When the generic SCMI code tears down a channel, it calls the chan_free
+callback function, defined by each transport. Since multiple protocols
+might share the same transport_info member, chan_free() might want to
+clean up the same member multiple times within the given SCMI transport
+implementation. In this case, it is SMC transport. This will lead to a NULL
+pointer dereference at the second time:
+
+ | scmi_protocol scmi_dev.1: Enabled polling mode TX channel - prot_id:16
+ | arm-scmi firmware:scmi: SCMI Notifications - Core Enabled.
+ | arm-scmi firmware:scmi: unable to communicate with SCMI
+ | Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
+ | Mem abort info:
+ | ESR = 0x0000000096000004
+ | EC = 0x25: DABT (current EL), IL = 32 bits
+ | SET = 0, FnV = 0
+ | EA = 0, S1PTW = 0
+ | FSC = 0x04: level 0 translation fault
+ | Data abort info:
+ | ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
+ | CM = 0, WnR = 0, TnD = 0, TagAccess = 0
+ | GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
+ | user pgtable: 4k pages, 48-bit VAs, pgdp=0000000881ef8000
+ | [0000000000000000] pgd=0000000000000000, p4d=0000000000000000
+ | Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
+ | Modules linked in:
+ | CPU: 4 PID: 1 Comm: swapper/0 Not tainted 6.7.0-rc2-00124-g455ef3d016c9-dirty #793
+ | Hardware name: FVP Base RevC (DT)
+ | pstate: 61400009 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
+ | pc : smc_chan_free+0x3c/0x6c
+ | lr : smc_chan_free+0x3c/0x6c
+ | Call trace:
+ | smc_chan_free+0x3c/0x6c
+ | idr_for_each+0x68/0xf8
+ | scmi_cleanup_channels.isra.0+0x2c/0x58
+ | scmi_probe+0x434/0x734
+ | platform_probe+0x68/0xd8
+ | really_probe+0x110/0x27c
+ | __driver_probe_device+0x78/0x12c
+ | driver_probe_device+0x3c/0x118
+ | __driver_attach+0x74/0x128
+ | bus_for_each_dev+0x78/0xe0
+ | driver_attach+0x24/0x30
+ | bus_add_driver+0xe4/0x1e8
+ | driver_register+0x60/0x128
+ | __platform_driver_register+0x28/0x34
+ | scmi_driver_init+0x84/0xc0
+ | do_one_initcall+0x78/0x33c
+ | kernel_init_freeable+0x2b8/0x51c
+ | kernel_init+0x24/0x130
+ | ret_from_fork+0x10/0x20
+ | Code: f0004701 910a0021 aa1403e5 97b91c70 (b9400280)
+ | ---[ end trace 0000000000000000 ]---
+
+Simply check for the struct pointer being NULL before trying to access
+its members, to avoid this situation.
+
+This was found when a transport doesn't really work (for instance no SMC
+service), the probe routines then tries to clean up, and triggers a crash.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Fixes: 1dc6558062da ("firmware: arm_scmi: Add smc/hvc transport")
+Reviewed-by: Cristian Marussi <cristian.marussi@arm.com>
+Link: https://lore.kernel.org/r/20240126122325.2039669-1-andre.przywara@arm.com
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/smc.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c
+index ac0bd51ef16a2..42ea308a2c1d5 100644
+--- a/drivers/firmware/arm_scmi/smc.c
++++ b/drivers/firmware/arm_scmi/smc.c
+@@ -171,6 +171,13 @@ static int smc_chan_free(int id, void *p, void *data)
+ struct scmi_chan_info *cinfo = p;
+ struct scmi_smc *scmi_info = cinfo->transport_info;
+
++ /*
++ * Different protocols might share the same chan info, so a previous
++ * smc_chan_free call might have already freed the structure.
++ */
++ if (!scmi_info)
++ return 0;
++
+ /* Ignore any possible further reception on the IRQ path */
+ if (scmi_info->irq > 0)
+ free_irq(scmi_info->irq, scmi_info);
+--
+2.43.0
+
--- /dev/null
+From e6201d4c217fc56523c2f7f50213807230b9fc82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Feb 2024 12:39:20 -0800
+Subject: fs: Fix rw_hint validation
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit ec16b147a55bfa14e858234eb7b1a7c8e7cd5021 ]
+
+Reject values that are valid rw_hints after truncation but not before
+truncation by passing an untruncated value to rw_hint_valid().
+
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
+Cc: Jeff Layton <jlayton@kernel.org>
+Cc: Chuck Lever <chuck.lever@oracle.com>
+Cc: Jens Axboe <axboe@kernel.dk>
+Cc: Stephen Rothwell <sfr@canb.auug.org.au>
+Fixes: 5657cb0797c4 ("fs/fcntl: use copy_to/from_user() for u64 types")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20240202203926.2478590-2-bvanassche@acm.org
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fcntl.c | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/fs/fcntl.c b/fs/fcntl.c
+index 146c9ab0cd4b7..0964e5dbf0cac 100644
+--- a/fs/fcntl.c
++++ b/fs/fcntl.c
+@@ -267,7 +267,7 @@ static int f_getowner_uids(struct file *filp, unsigned long arg)
+ }
+ #endif
+
+-static bool rw_hint_valid(enum rw_hint hint)
++static bool rw_hint_valid(u64 hint)
+ {
+ switch (hint) {
+ case RWH_WRITE_LIFE_NOT_SET:
+@@ -287,19 +287,17 @@ static long fcntl_rw_hint(struct file *file, unsigned int cmd,
+ {
+ struct inode *inode = file_inode(file);
+ u64 __user *argp = (u64 __user *)arg;
+- enum rw_hint hint;
+- u64 h;
++ u64 hint;
+
+ switch (cmd) {
+ case F_GET_RW_HINT:
+- h = inode->i_write_hint;
+- if (copy_to_user(argp, &h, sizeof(*argp)))
++ hint = inode->i_write_hint;
++ if (copy_to_user(argp, &hint, sizeof(*argp)))
+ return -EFAULT;
+ return 0;
+ case F_SET_RW_HINT:
+- if (copy_from_user(&h, argp, sizeof(h)))
++ if (copy_from_user(&hint, argp, sizeof(hint)))
+ return -EFAULT;
+- hint = (enum rw_hint) h;
+ if (!rw_hint_valid(hint))
+ return -EINVAL;
+
+--
+2.43.0
+
--- /dev/null
+From c80f23af04d37e535d603b50bda5b5aa2b940d6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Feb 2024 21:23:34 +0100
+Subject: fs/select: rework stack allocation hack for clang
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit ddb9fd7a544088ed70eccbb9f85e9cc9952131c1 ]
+
+A while ago, we changed the way that select() and poll() preallocate
+a temporary buffer just under the size of the static warning limit of
+1024 bytes, as clang was frequently going slightly above that limit.
+
+The warnings have recently returned and I took another look. As it turns
+out, clang is not actually inherently worse at reserving stack space,
+it just happens to inline do_select() into core_sys_select(), while gcc
+never inlines it.
+
+Annotate do_select() to never be inlined and in turn remove the special
+case for the allocation size. This should give the same behavior for
+both clang and gcc all the time and once more avoids those warnings.
+
+Fixes: ad312f95d41c ("fs/select: avoid clang stack usage warning")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20240216202352.2492798-1-arnd@kernel.org
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Reviewed-by: Andi Kleen <ak@linux.intel.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/select.c | 2 +-
+ include/linux/poll.h | 4 ----
+ 2 files changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/fs/select.c b/fs/select.c
+index 0ee55af1a55c2..d4d881d439dcd 100644
+--- a/fs/select.c
++++ b/fs/select.c
+@@ -476,7 +476,7 @@ static inline void wait_key_set(poll_table *wait, unsigned long in,
+ wait->_key |= POLLOUT_SET;
+ }
+
+-static int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time)
++static noinline_for_stack int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time)
+ {
+ ktime_t expire, *to = NULL;
+ struct poll_wqueues table;
+diff --git a/include/linux/poll.h b/include/linux/poll.h
+index a9e0e1c2d1f2f..d1ea4f3714a84 100644
+--- a/include/linux/poll.h
++++ b/include/linux/poll.h
+@@ -14,11 +14,7 @@
+
+ /* ~832 bytes of stack space used max in sys_select/sys_poll before allocating
+ additional memory. */
+-#ifdef __clang__
+-#define MAX_STACK_ALLOC 768
+-#else
+ #define MAX_STACK_ALLOC 832
+-#endif
+ #define FRONTEND_STACK_ALLOC 256
+ #define SELECT_STACK_ALLOC FRONTEND_STACK_ALLOC
+ #define POLL_STACK_ALLOC FRONTEND_STACK_ALLOC
+--
+2.43.0
+
--- /dev/null
+From a62e0ac91b179a41590e10bb42e44e9e3de02b7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Feb 2024 12:28:03 +0100
+Subject: gpio: nomadik: fix offset bug in nmk_pmx_set()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Théo Lebrun <theo.lebrun@bootlin.com>
+
+[ Upstream commit 53cf6b72e074864b94ade97dcb6f30b5ac1a82dc ]
+
+Previously, the statement looked like:
+
+ slpm[x] &= ~BIT(g->grp.pins[i]);
+
+Where:
+ - slpm is a unsigned int pointer;
+ - g->grp.pins[i] is a pin number. It can grow to more than 32.
+
+The expected shift amount is a pin bank offset.
+
+This bug does not occur on every group or pin: the altsetting must be
+NMK_GPIO_ALT_C and the pin must be 32 or above. It might have occured.
+For example, in pinctrl-nomadik-db8500.c, pin group i2c3_c_2 has the
+right altsetting and pins 229 and 230.
+
+Fixes: dbfe8ca259e1 ("pinctrl/nomadik: implement pin multiplexing")
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
+Link: https://lore.kernel.org/r/20240228-mbly-gpio-v2-5-3ba757474006@bootlin.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/nomadik/pinctrl-nomadik.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+index f7d02513d8cc1..e79037dc85796 100644
+--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
++++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+@@ -1571,8 +1571,10 @@ static int nmk_pmx_set(struct pinctrl_dev *pctldev, unsigned function,
+ * Then mask the pins that need to be sleeping now when we're
+ * switching to the ALT C function.
+ */
+- for (i = 0; i < g->grp.npins; i++)
+- slpm[g->grp.pins[i] / NMK_GPIO_PER_CHIP] &= ~BIT(g->grp.pins[i]);
++ for (i = 0; i < g->grp.npins; i++) {
++ unsigned int bit = g->grp.pins[i] % NMK_GPIO_PER_CHIP;
++ slpm[g->grp.pins[i] / NMK_GPIO_PER_CHIP] &= ~BIT(bit);
++ }
+ nmk_gpio_glitch_slpm_init(slpm);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From b8d7bea68012e7dabe5f45a9eea430d5e16da192 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jan 2024 21:58:57 +0100
+Subject: gpio: vf610: allow disabling the vf610 driver
+
+From: Martin Kaiser <martin@kaiser.cx>
+
+[ Upstream commit f57595788244a838deec2d3be375291327cbc035 ]
+
+The vf610 gpio driver is enabled by default for all i.MX machines,
+without any option to disable it in a board-specific config file.
+
+Most i.MX chipsets have no hardware for this driver. Change the default
+to enable GPIO_VF610 for SOC_VF610 and disable it otherwise.
+
+Add a text description after the bool type, this makes the driver
+selectable by make config etc.
+
+Fixes: 30a35c07d9e9 ("gpio: vf610: drop the SOC_VF610 dependency for GPIO_VF610")
+Signed-off-by: Martin Kaiser <martin@kaiser.cx>
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/Kconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
+index 3e8e5f4ffa59f..700f71c954956 100644
+--- a/drivers/gpio/Kconfig
++++ b/drivers/gpio/Kconfig
+@@ -679,7 +679,8 @@ config GPIO_UNIPHIER
+ Say yes here to support UniPhier GPIOs.
+
+ config GPIO_VF610
+- def_bool y
++ bool "VF610 GPIO support"
++ default y if SOC_VF610
+ depends on ARCH_MXC
+ select GPIOLIB_IRQCHIP
+ help
+--
+2.43.0
+
--- /dev/null
+From 5f317d46e206ef6e8b0183f82cfd69987ca30ad1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Feb 2024 20:11:42 +0530
+Subject: HID: amd_sfh: Avoid disabling the interrupt
+
+From: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+
+[ Upstream commit c1db0073212ef39d5a46c2aea5e49bf884375ce4 ]
+
+HP ProBook x360 435 G7 using older version of firmware which doesn't
+support disabling the interrupt for all commands. Hence avoid disabling
+the interrupt for that particular model.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=218104
+Fixes: b300667b33b2 ("HID: amd_sfh: Disable the interrupt for all command")
+Co-developed-by: Akshata MukundShetty <akshata.mukundshetty@amd.com>
+Signed-off-by: Akshata MukundShetty <akshata.mukundshetty@amd.com>
+Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 30 +++++++++++++++++++++++---
+ 1 file changed, 27 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+index c936d6a51c0cd..9c963ad27f9d1 100644
+--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
++++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+@@ -34,6 +34,8 @@ static int sensor_mask_override = -1;
+ module_param_named(sensor_mask, sensor_mask_override, int, 0444);
+ MODULE_PARM_DESC(sensor_mask, "override the detected sensors mask");
+
++static bool intr_disable = true;
++
+ static int amd_sfh_wait_response_v2(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts)
+ {
+ union cmd_response cmd_resp;
+@@ -54,7 +56,7 @@ static void amd_start_sensor_v2(struct amd_mp2_dev *privdata, struct amd_mp2_sen
+
+ cmd_base.ul = 0;
+ cmd_base.cmd_v2.cmd_id = ENABLE_SENSOR;
+- cmd_base.cmd_v2.intr_disable = 1;
++ cmd_base.cmd_v2.intr_disable = intr_disable;
+ cmd_base.cmd_v2.period = info.period;
+ cmd_base.cmd_v2.sensor_id = info.sensor_idx;
+ cmd_base.cmd_v2.length = 16;
+@@ -72,7 +74,7 @@ static void amd_stop_sensor_v2(struct amd_mp2_dev *privdata, u16 sensor_idx)
+
+ cmd_base.ul = 0;
+ cmd_base.cmd_v2.cmd_id = DISABLE_SENSOR;
+- cmd_base.cmd_v2.intr_disable = 1;
++ cmd_base.cmd_v2.intr_disable = intr_disable;
+ cmd_base.cmd_v2.period = 0;
+ cmd_base.cmd_v2.sensor_id = sensor_idx;
+ cmd_base.cmd_v2.length = 16;
+@@ -86,7 +88,7 @@ static void amd_stop_all_sensor_v2(struct amd_mp2_dev *privdata)
+ union sfh_cmd_base cmd_base;
+
+ cmd_base.cmd_v2.cmd_id = STOP_ALL_SENSORS;
+- cmd_base.cmd_v2.intr_disable = 1;
++ cmd_base.cmd_v2.intr_disable = intr_disable;
+ cmd_base.cmd_v2.period = 0;
+ cmd_base.cmd_v2.sensor_id = 0;
+
+@@ -288,6 +290,26 @@ int amd_sfh_irq_init(struct amd_mp2_dev *privdata)
+ return 0;
+ }
+
++static int mp2_disable_intr(const struct dmi_system_id *id)
++{
++ intr_disable = false;
++ return 0;
++}
++
++static const struct dmi_system_id dmi_sfh_table[] = {
++ {
++ /*
++ * https://bugzilla.kernel.org/show_bug.cgi?id=218104
++ */
++ .callback = mp2_disable_intr,
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "HP"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook x360 435 G7"),
++ },
++ },
++ {}
++};
++
+ static const struct dmi_system_id dmi_nodevs[] = {
+ {
+ /*
+@@ -311,6 +333,8 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
+ if (dmi_first_match(dmi_nodevs))
+ return -ENODEV;
+
++ dmi_check_system(dmi_sfh_table);
++
+ privdata = devm_kzalloc(&pdev->dev, sizeof(*privdata), GFP_KERNEL);
+ if (!privdata)
+ return -ENOMEM;
+--
+2.43.0
+
--- /dev/null
+From 7813b8b8bed0005783ab0c1be51d5052c09f82c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Feb 2024 20:11:41 +0530
+Subject: HID: amd_sfh: Update HPD sensor structure elements
+
+From: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+
+[ Upstream commit bbf0dec30696638b8bdc28cb2f5bf23f8d760b52 ]
+
+HPD sensor data is not populating properly because of wrong order of HPD
+sensor structure elements. So update the order of structure elements to
+match the HPD sensor data received from the firmware.
+
+Fixes: 24a31ea94922 ("HID: amd_sfh: Add initial support for HPD sensor")
+Co-developed-by: Akshata MukundShetty <akshata.mukundshetty@amd.com>
+Signed-off-by: Akshata MukundShetty <akshata.mukundshetty@amd.com>
+Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/amd-sfh-hid/amd_sfh_pcie.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
+index dfb7cabd82efe..2b125cd9742cb 100644
+--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
++++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
+@@ -89,10 +89,10 @@ enum mem_use_type {
+ struct hpd_status {
+ union {
+ struct {
+- u32 human_presence_report : 4;
+- u32 human_presence_actual : 4;
+- u32 probablity : 8;
+ u32 object_distance : 16;
++ u32 probablity : 8;
++ u32 human_presence_actual : 4;
++ u32 human_presence_report : 4;
+ } shpd;
+ u32 val;
+ };
+--
+2.43.0
+
--- /dev/null
+From ae771fbbae9c128a6410460141e23f9a31ddc4d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Dec 2023 21:12:13 +0200
+Subject: HID: lenovo: Add middleclick_workaround sysfs knob for cptkbd
+
+From: Mikhail Khvainitski <me@khvoinitsky.org>
+
+[ Upstream commit 2814646f76f8518326964f12ff20aaee70ba154d ]
+
+Previous attempt to autodetect well-behaving patched firmware
+introduced in commit 46a0a2c96f0f ("HID: lenovo: Detect quirk-free fw
+on cptkbd and stop applying workaround") has shown that there are
+false-positives on original firmware (on both 1st gen and 2nd gen
+keyboards) which causes the middle button click workaround to be
+mistakenly disabled.
+
+This commit adds explicit parameter to sysfs to control this
+workaround.
+
+Fixes: 46a0a2c96f0f ("HID: lenovo: Detect quirk-free fw on cptkbd and stop applying workaround")
+Fixes: 43527a0094c1 ("HID: lenovo: Restrict detection of patched firmware only to USB cptkbd")
+Signed-off-by: Mikhail Khvainitski <me@khvoinitsky.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-lenovo.c | 57 +++++++++++++++++++++++++++-------------
+ 1 file changed, 39 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c
+index 149a3c74346b4..f86c1ea83a037 100644
+--- a/drivers/hid/hid-lenovo.c
++++ b/drivers/hid/hid-lenovo.c
+@@ -54,10 +54,10 @@ struct lenovo_drvdata {
+ /* 0: Up
+ * 1: Down (undecided)
+ * 2: Scrolling
+- * 3: Patched firmware, disable workaround
+ */
+ u8 middlebutton_state;
+ bool fn_lock;
++ bool middleclick_workaround_cptkbd;
+ };
+
+ #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
+@@ -621,6 +621,36 @@ static ssize_t attr_sensitivity_store_cptkbd(struct device *dev,
+ return count;
+ }
+
++static ssize_t attr_middleclick_workaround_show_cptkbd(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct hid_device *hdev = to_hid_device(dev);
++ struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev);
++
++ return snprintf(buf, PAGE_SIZE, "%u\n",
++ cptkbd_data->middleclick_workaround_cptkbd);
++}
++
++static ssize_t attr_middleclick_workaround_store_cptkbd(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf,
++ size_t count)
++{
++ struct hid_device *hdev = to_hid_device(dev);
++ struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev);
++ int value;
++
++ if (kstrtoint(buf, 10, &value))
++ return -EINVAL;
++ if (value < 0 || value > 1)
++ return -EINVAL;
++
++ cptkbd_data->middleclick_workaround_cptkbd = !!value;
++
++ return count;
++}
++
+
+ static struct device_attribute dev_attr_fn_lock =
+ __ATTR(fn_lock, S_IWUSR | S_IRUGO,
+@@ -632,10 +662,16 @@ static struct device_attribute dev_attr_sensitivity_cptkbd =
+ attr_sensitivity_show_cptkbd,
+ attr_sensitivity_store_cptkbd);
+
++static struct device_attribute dev_attr_middleclick_workaround_cptkbd =
++ __ATTR(middleclick_workaround, S_IWUSR | S_IRUGO,
++ attr_middleclick_workaround_show_cptkbd,
++ attr_middleclick_workaround_store_cptkbd);
++
+
+ static struct attribute *lenovo_attributes_cptkbd[] = {
+ &dev_attr_fn_lock.attr,
+ &dev_attr_sensitivity_cptkbd.attr,
++ &dev_attr_middleclick_workaround_cptkbd.attr,
+ NULL
+ };
+
+@@ -686,23 +722,7 @@ static int lenovo_event_cptkbd(struct hid_device *hdev,
+ {
+ struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev);
+
+- if (cptkbd_data->middlebutton_state != 3) {
+- /* REL_X and REL_Y events during middle button pressed
+- * are only possible on patched, bug-free firmware
+- * so set middlebutton_state to 3
+- * to never apply workaround anymore
+- */
+- if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD &&
+- cptkbd_data->middlebutton_state == 1 &&
+- usage->type == EV_REL &&
+- (usage->code == REL_X || usage->code == REL_Y)) {
+- cptkbd_data->middlebutton_state = 3;
+- /* send middle button press which was hold before */
+- input_event(field->hidinput->input,
+- EV_KEY, BTN_MIDDLE, 1);
+- input_sync(field->hidinput->input);
+- }
+-
++ if (cptkbd_data->middleclick_workaround_cptkbd) {
+ /* "wheel" scroll events */
+ if (usage->type == EV_REL && (usage->code == REL_WHEEL ||
+ usage->code == REL_HWHEEL)) {
+@@ -1166,6 +1186,7 @@ static int lenovo_probe_cptkbd(struct hid_device *hdev)
+ cptkbd_data->middlebutton_state = 0;
+ cptkbd_data->fn_lock = true;
+ cptkbd_data->sensitivity = 0x05;
++ cptkbd_data->middleclick_workaround_cptkbd = true;
+ lenovo_features_set_cptkbd(hdev);
+
+ ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd);
+--
+2.43.0
+
--- /dev/null
+From 38d29d1d9268cabfcdcb9d177dd7c312c856ca1a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Feb 2024 15:57:11 -0800
+Subject: igb: Fix missing time sync events
+
+From: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+
+[ Upstream commit ee14cc9ea19ba9678177e2224a9c58cce5937c73 ]
+
+Fix "double" clearing of interrupts, which can cause external events
+or timestamps to be missed.
+
+The E1000_TSIRC Time Sync Interrupt Cause register can be cleared in two
+ways, by either reading it or by writing '1' into the specific cause
+bit. This is documented in section 8.16.1.
+
+The following flow was used:
+ 1. read E1000_TSIRC into 'tsicr';
+ 2. handle the interrupts present into 'tsirc' and mark them in 'ack';
+ 3. write 'ack' into E1000_TSICR;
+
+As both (1) and (3) will clear the interrupt cause, if the same
+interrupt happens again between (1) and (3) it will be ignored,
+causing events to be missed.
+
+Remove the extra clear in (3).
+
+Fixes: 00c65578b47b ("igb: enable internal PPS for the i210")
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igb/igb_main.c | 23 +++++------------------
+ 1 file changed, 5 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
+index 45ce4ed16146e..81d9a5338be5e 100644
+--- a/drivers/net/ethernet/intel/igb/igb_main.c
++++ b/drivers/net/ethernet/intel/igb/igb_main.c
+@@ -6926,44 +6926,31 @@ static void igb_extts(struct igb_adapter *adapter, int tsintr_tt)
+ static void igb_tsync_interrupt(struct igb_adapter *adapter)
+ {
+ struct e1000_hw *hw = &adapter->hw;
+- u32 ack = 0, tsicr = rd32(E1000_TSICR);
++ u32 tsicr = rd32(E1000_TSICR);
+ struct ptp_clock_event event;
+
+ if (tsicr & TSINTR_SYS_WRAP) {
+ event.type = PTP_CLOCK_PPS;
+ if (adapter->ptp_caps.pps)
+ ptp_clock_event(adapter->ptp_clock, &event);
+- ack |= TSINTR_SYS_WRAP;
+ }
+
+ if (tsicr & E1000_TSICR_TXTS) {
+ /* retrieve hardware timestamp */
+ schedule_work(&adapter->ptp_tx_work);
+- ack |= E1000_TSICR_TXTS;
+ }
+
+- if (tsicr & TSINTR_TT0) {
++ if (tsicr & TSINTR_TT0)
+ igb_perout(adapter, 0);
+- ack |= TSINTR_TT0;
+- }
+
+- if (tsicr & TSINTR_TT1) {
++ if (tsicr & TSINTR_TT1)
+ igb_perout(adapter, 1);
+- ack |= TSINTR_TT1;
+- }
+
+- if (tsicr & TSINTR_AUTT0) {
++ if (tsicr & TSINTR_AUTT0)
+ igb_extts(adapter, 0);
+- ack |= TSINTR_AUTT0;
+- }
+
+- if (tsicr & TSINTR_AUTT1) {
++ if (tsicr & TSINTR_AUTT1)
+ igb_extts(adapter, 1);
+- ack |= TSINTR_AUTT1;
+- }
+-
+- /* acknowledge the interrupts */
+- wr32(E1000_TSICR, ack);
+ }
+
+ static irqreturn_t igb_msix_other(int irq, void *data)
+--
+2.43.0
+
--- /dev/null
+From e1f0ab5414f6081c99aa73a66fff22d1014b5175 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jan 2024 11:25:56 +0000
+Subject: inet_diag: annotate data-races around inet_diag_table[]
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit e50e10ae5d81ddb41547114bfdc5edc04422f082 ]
+
+inet_diag_lock_handler() reads inet_diag_table[proto] locklessly.
+
+Use READ_ONCE()/WRITE_ONCE() annotations to avoid potential issues.
+
+Fixes: d523a328fb02 ("[INET]: Fix inet_diag dead-lock regression")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Guillaume Nault <gnault@redhat.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/inet_diag.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
+index f7426926a1041..8f690a6e61baa 100644
+--- a/net/ipv4/inet_diag.c
++++ b/net/ipv4/inet_diag.c
+@@ -57,7 +57,7 @@ static const struct inet_diag_handler *inet_diag_lock_handler(int proto)
+ return ERR_PTR(-ENOENT);
+ }
+
+- if (!inet_diag_table[proto])
++ if (!READ_ONCE(inet_diag_table[proto]))
+ sock_load_diag_module(AF_INET, proto);
+
+ mutex_lock(&inet_diag_table_mutex);
+@@ -1419,7 +1419,7 @@ int inet_diag_register(const struct inet_diag_handler *h)
+ mutex_lock(&inet_diag_table_mutex);
+ err = -EEXIST;
+ if (!inet_diag_table[type]) {
+- inet_diag_table[type] = h;
++ WRITE_ONCE(inet_diag_table[type], h);
+ err = 0;
+ }
+ mutex_unlock(&inet_diag_table_mutex);
+@@ -1436,7 +1436,7 @@ void inet_diag_unregister(const struct inet_diag_handler *h)
+ return;
+
+ mutex_lock(&inet_diag_table_mutex);
+- inet_diag_table[type] = NULL;
++ WRITE_ONCE(inet_diag_table[type], NULL);
+ mutex_unlock(&inet_diag_table_mutex);
+ }
+ EXPORT_SYMBOL_GPL(inet_diag_unregister);
+--
+2.43.0
+
--- /dev/null
+From 9193c7c324f4db41897d17ceaaae71e9e447cd80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Mar 2024 19:43:48 +0500
+Subject: io_uring/net: correct the type of variable
+
+From: Muhammad Usama Anjum <usama.anjum@collabora.com>
+
+[ Upstream commit 86bcacc957fc2d0403aa0e652757eec59a5fd7ca ]
+
+The namelen is of type int. It shouldn't be made size_t which is
+unsigned. The signed number is needed for error checking before use.
+
+Fixes: c55978024d12 ("io_uring/net: move receive multishot out of the generic msghdr path")
+Signed-off-by: Muhammad Usama Anjum <usama.anjum@collabora.com>
+Link: https://lore.kernel.org/r/20240301144349.2807544-1-usama.anjum@collabora.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/net.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/io_uring/net.c b/io_uring/net.c
+index 9fc0ffb0b6c12..0d4ee3d738fbf 100644
+--- a/io_uring/net.c
++++ b/io_uring/net.c
+@@ -516,7 +516,7 @@ int io_send(struct io_kiocb *req, unsigned int issue_flags)
+
+ static int io_recvmsg_mshot_prep(struct io_kiocb *req,
+ struct io_async_msghdr *iomsg,
+- size_t namelen, size_t controllen)
++ int namelen, size_t controllen)
+ {
+ if ((req->flags & (REQ_F_APOLL_MULTISHOT|REQ_F_BUFFER_SELECT)) ==
+ (REQ_F_APOLL_MULTISHOT|REQ_F_BUFFER_SELECT)) {
+--
+2.43.0
+
--- /dev/null
+From 466427d64e77b919436cf3dbef3c44069d814aa0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Mar 2024 18:29:39 +0300
+Subject: io_uring/net: fix overflow check in io_recvmsg_mshot_prep()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 8ede3db5061bb1fe28e2c9683329aafa89d2b1b4 ]
+
+The "controllen" variable is type size_t (unsigned long). Casting it
+to int could lead to an integer underflow.
+
+The check_add_overflow() function considers the type of the destination
+which is type int. If we add two positive values and the result cannot
+fit in an integer then that's counted as an overflow.
+
+However, if we cast "controllen" to an int and it turns negative, then
+negative values *can* fit into an int type so there is no overflow.
+
+Good: 100 + (unsigned long)-4 = 96 <-- overflow
+ Bad: 100 + (int)-4 = 96 <-- no overflow
+
+I deleted the cast of the sizeof() as well. That's not a bug but the
+cast is unnecessary.
+
+Fixes: 9b0fc3c054ff ("io_uring: fix types in io_recvmsg_multishot_overflow")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/r/138bd2e2-ede8-4bcc-aa7b-f3d9de167a37@moroto.mountain
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/net.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/io_uring/net.c b/io_uring/net.c
+index b273914ed99f0..9fc0ffb0b6c12 100644
+--- a/io_uring/net.c
++++ b/io_uring/net.c
+@@ -524,10 +524,10 @@ static int io_recvmsg_mshot_prep(struct io_kiocb *req,
+
+ if (unlikely(namelen < 0))
+ return -EOVERFLOW;
+- if (check_add_overflow((int)sizeof(struct io_uring_recvmsg_out),
++ if (check_add_overflow(sizeof(struct io_uring_recvmsg_out),
+ namelen, &hdr))
+ return -EOVERFLOW;
+- if (check_add_overflow(hdr, (int)controllen, &hdr))
++ if (check_add_overflow(hdr, controllen, &hdr))
+ return -EOVERFLOW;
+
+ iomsg->namelen = namelen;
+--
+2.43.0
+
--- /dev/null
+From a2cd534b7a8e57e4769f8a4b7ac1b162c01884df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Feb 2024 11:09:20 -0700
+Subject: io_uring/net: move receive multishot out of the generic msghdr path
+
+From: Jens Axboe <axboe@kernel.dk>
+
+[ Upstream commit c55978024d123d43808ab393a0a4ce3ce8568150 ]
+
+Move the actual user_msghdr / compat_msghdr into the send and receive
+sides, respectively, so we can move the uaddr receive handling into its
+own handler, and ditto the multishot with buffer selection logic.
+
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: 8ede3db5061b ("io_uring/net: fix overflow check in io_recvmsg_mshot_prep()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/net.c | 161 ++++++++++++++++++++++++++++---------------------
+ 1 file changed, 91 insertions(+), 70 deletions(-)
+
+diff --git a/io_uring/net.c b/io_uring/net.c
+index c770961079749..b273914ed99f0 100644
+--- a/io_uring/net.c
++++ b/io_uring/net.c
+@@ -183,46 +183,26 @@ static int io_setup_async_msg(struct io_kiocb *req,
+ return -EAGAIN;
+ }
+
+-static bool io_recvmsg_multishot_overflow(struct io_async_msghdr *iomsg)
+-{
+- int hdr;
+-
+- if (iomsg->namelen < 0)
+- return true;
+- if (check_add_overflow((int)sizeof(struct io_uring_recvmsg_out),
+- iomsg->namelen, &hdr))
+- return true;
+- if (check_add_overflow(hdr, (int)iomsg->controllen, &hdr))
+- return true;
+-
+- return false;
+-}
+-
+ #ifdef CONFIG_COMPAT
+-static int __io_compat_msg_copy_hdr(struct io_kiocb *req,
+- struct io_async_msghdr *iomsg,
+- struct sockaddr __user **addr, int ddir)
++static int io_compat_msg_copy_hdr(struct io_kiocb *req,
++ struct io_async_msghdr *iomsg,
++ struct compat_msghdr *msg, int ddir)
+ {
+ struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
+- struct compat_msghdr msg;
+ struct compat_iovec __user *uiov;
+ int ret;
+
+- if (copy_from_user(&msg, sr->umsg_compat, sizeof(msg)))
++ if (copy_from_user(msg, sr->umsg_compat, sizeof(*msg)))
+ return -EFAULT;
+
+- ret = __get_compat_msghdr(&iomsg->msg, &msg, addr);
+- if (ret)
+- return ret;
+-
+- uiov = compat_ptr(msg.msg_iov);
++ uiov = compat_ptr(msg->msg_iov);
+ if (req->flags & REQ_F_BUFFER_SELECT) {
+ compat_ssize_t clen;
+
+ iomsg->free_iov = NULL;
+- if (msg.msg_iovlen == 0) {
++ if (msg->msg_iovlen == 0) {
+ sr->len = 0;
+- } else if (msg.msg_iovlen > 1) {
++ } else if (msg->msg_iovlen > 1) {
+ return -EINVAL;
+ } else {
+ if (!access_ok(uiov, sizeof(*uiov)))
+@@ -234,18 +214,11 @@ static int __io_compat_msg_copy_hdr(struct io_kiocb *req,
+ sr->len = clen;
+ }
+
+- if (ddir == ITER_DEST && req->flags & REQ_F_APOLL_MULTISHOT) {
+- iomsg->namelen = msg.msg_namelen;
+- iomsg->controllen = msg.msg_controllen;
+- if (io_recvmsg_multishot_overflow(iomsg))
+- return -EOVERFLOW;
+- }
+-
+ return 0;
+ }
+
+ iomsg->free_iov = iomsg->fast_iov;
+- ret = __import_iovec(ddir, (struct iovec __user *)uiov, msg.msg_iovlen,
++ ret = __import_iovec(ddir, (struct iovec __user *)uiov, msg->msg_iovlen,
+ UIO_FASTIOV, &iomsg->free_iov,
+ &iomsg->msg.msg_iter, true);
+ if (unlikely(ret < 0))
+@@ -255,47 +228,35 @@ static int __io_compat_msg_copy_hdr(struct io_kiocb *req,
+ }
+ #endif
+
+-static int __io_msg_copy_hdr(struct io_kiocb *req, struct io_async_msghdr *iomsg,
+- struct sockaddr __user **addr, int ddir)
++static int io_msg_copy_hdr(struct io_kiocb *req, struct io_async_msghdr *iomsg,
++ struct user_msghdr *msg, int ddir)
+ {
+ struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
+- struct user_msghdr msg;
+ int ret;
+
+- if (copy_from_user(&msg, sr->umsg, sizeof(*sr->umsg)))
++ if (copy_from_user(msg, sr->umsg, sizeof(*sr->umsg)))
+ return -EFAULT;
+
+- ret = __copy_msghdr(&iomsg->msg, &msg, addr);
+- if (ret)
+- return ret;
+-
+ if (req->flags & REQ_F_BUFFER_SELECT) {
+- if (msg.msg_iovlen == 0) {
++ if (msg->msg_iovlen == 0) {
+ sr->len = iomsg->fast_iov[0].iov_len = 0;
+ iomsg->fast_iov[0].iov_base = NULL;
+ iomsg->free_iov = NULL;
+- } else if (msg.msg_iovlen > 1) {
++ } else if (msg->msg_iovlen > 1) {
+ return -EINVAL;
+ } else {
+- if (copy_from_user(iomsg->fast_iov, msg.msg_iov,
+- sizeof(*msg.msg_iov)))
++ if (copy_from_user(iomsg->fast_iov, msg->msg_iov,
++ sizeof(*msg->msg_iov)))
+ return -EFAULT;
+ sr->len = iomsg->fast_iov[0].iov_len;
+ iomsg->free_iov = NULL;
+ }
+
+- if (ddir == ITER_DEST && req->flags & REQ_F_APOLL_MULTISHOT) {
+- iomsg->namelen = msg.msg_namelen;
+- iomsg->controllen = msg.msg_controllen;
+- if (io_recvmsg_multishot_overflow(iomsg))
+- return -EOVERFLOW;
+- }
+-
+ return 0;
+ }
+
+ iomsg->free_iov = iomsg->fast_iov;
+- ret = __import_iovec(ddir, msg.msg_iov, msg.msg_iovlen, UIO_FASTIOV,
++ ret = __import_iovec(ddir, msg->msg_iov, msg->msg_iovlen, UIO_FASTIOV,
+ &iomsg->free_iov, &iomsg->msg.msg_iter, false);
+ if (unlikely(ret < 0))
+ return ret;
+@@ -303,30 +264,34 @@ static int __io_msg_copy_hdr(struct io_kiocb *req, struct io_async_msghdr *iomsg
+ return 0;
+ }
+
+-static int io_msg_copy_hdr(struct io_kiocb *req, struct io_async_msghdr *iomsg,
+- struct sockaddr __user **addr, int ddir)
++static int io_sendmsg_copy_hdr(struct io_kiocb *req,
++ struct io_async_msghdr *iomsg)
+ {
++ struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
++ struct user_msghdr msg;
++ int ret;
++
+ iomsg->msg.msg_name = &iomsg->addr;
+ iomsg->msg.msg_iter.nr_segs = 0;
+
+ #ifdef CONFIG_COMPAT
+- if (req->ctx->compat)
+- return __io_compat_msg_copy_hdr(req, iomsg, addr, ddir);
+-#endif
++ if (unlikely(req->ctx->compat)) {
++ struct compat_msghdr cmsg;
+
+- return __io_msg_copy_hdr(req, iomsg, addr, ddir);
+-}
++ ret = io_compat_msg_copy_hdr(req, iomsg, &cmsg, ITER_SOURCE);
++ if (unlikely(ret))
++ return ret;
+
+-static int io_sendmsg_copy_hdr(struct io_kiocb *req,
+- struct io_async_msghdr *iomsg)
+-{
+- struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
+- int ret;
++ return __get_compat_msghdr(&iomsg->msg, &cmsg, NULL);
++ }
++#endif
+
+- ret = io_msg_copy_hdr(req, iomsg, NULL, ITER_SOURCE);
+- if (ret)
++ ret = io_msg_copy_hdr(req, iomsg, &msg, ITER_SOURCE);
++ if (unlikely(ret))
+ return ret;
+
++ ret = __copy_msghdr(&iomsg->msg, &msg, NULL);
++
+ /* save msg_control as sys_sendmsg() overwrites it */
+ sr->msg_control = iomsg->msg.msg_control_user;
+ return ret;
+@@ -549,10 +514,66 @@ int io_send(struct io_kiocb *req, unsigned int issue_flags)
+ return IOU_OK;
+ }
+
++static int io_recvmsg_mshot_prep(struct io_kiocb *req,
++ struct io_async_msghdr *iomsg,
++ size_t namelen, size_t controllen)
++{
++ if ((req->flags & (REQ_F_APOLL_MULTISHOT|REQ_F_BUFFER_SELECT)) ==
++ (REQ_F_APOLL_MULTISHOT|REQ_F_BUFFER_SELECT)) {
++ int hdr;
++
++ if (unlikely(namelen < 0))
++ return -EOVERFLOW;
++ if (check_add_overflow((int)sizeof(struct io_uring_recvmsg_out),
++ namelen, &hdr))
++ return -EOVERFLOW;
++ if (check_add_overflow(hdr, (int)controllen, &hdr))
++ return -EOVERFLOW;
++
++ iomsg->namelen = namelen;
++ iomsg->controllen = controllen;
++ return 0;
++ }
++
++ return 0;
++}
++
+ static int io_recvmsg_copy_hdr(struct io_kiocb *req,
+ struct io_async_msghdr *iomsg)
+ {
+- return io_msg_copy_hdr(req, iomsg, &iomsg->uaddr, ITER_DEST);
++ struct user_msghdr msg;
++ int ret;
++
++ iomsg->msg.msg_name = &iomsg->addr;
++ iomsg->msg.msg_iter.nr_segs = 0;
++
++#ifdef CONFIG_COMPAT
++ if (unlikely(req->ctx->compat)) {
++ struct compat_msghdr cmsg;
++
++ ret = io_compat_msg_copy_hdr(req, iomsg, &cmsg, ITER_DEST);
++ if (unlikely(ret))
++ return ret;
++
++ ret = __get_compat_msghdr(&iomsg->msg, &cmsg, &iomsg->uaddr);
++ if (unlikely(ret))
++ return ret;
++
++ return io_recvmsg_mshot_prep(req, iomsg, cmsg.msg_namelen,
++ cmsg.msg_controllen);
++ }
++#endif
++
++ ret = io_msg_copy_hdr(req, iomsg, &msg, ITER_DEST);
++ if (unlikely(ret))
++ return ret;
++
++ ret = __copy_msghdr(&iomsg->msg, &msg, &iomsg->uaddr);
++ if (unlikely(ret))
++ return ret;
++
++ return io_recvmsg_mshot_prep(req, iomsg, msg.msg_namelen,
++ msg.msg_controllen);
+ }
+
+ int io_recvmsg_prep_async(struct io_kiocb *req)
+--
+2.43.0
+
--- /dev/null
+From 1077925268733acf2abed09aaae79ab07bd2e23b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Feb 2024 14:16:47 -0700
+Subject: io_uring/net: unify how recvmsg and sendmsg copy in the msghdr
+
+From: Jens Axboe <axboe@kernel.dk>
+
+[ Upstream commit 52307ac4f2b507f60bae6df5be938d35e199c688 ]
+
+For recvmsg, we roll our own since we support buffer selections. This
+isn't the case for sendmsg right now, but in preparation for doing so,
+make the recvmsg copy helpers generic so we can call them from the
+sendmsg side as well.
+
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: 8ede3db5061b ("io_uring/net: fix overflow check in io_recvmsg_mshot_prep()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/net.c | 271 ++++++++++++++++++++++++++-----------------------
+ 1 file changed, 142 insertions(+), 129 deletions(-)
+
+diff --git a/io_uring/net.c b/io_uring/net.c
+index c062ce66af12c..c770961079749 100644
+--- a/io_uring/net.c
++++ b/io_uring/net.c
+@@ -183,16 +183,150 @@ static int io_setup_async_msg(struct io_kiocb *req,
+ return -EAGAIN;
+ }
+
++static bool io_recvmsg_multishot_overflow(struct io_async_msghdr *iomsg)
++{
++ int hdr;
++
++ if (iomsg->namelen < 0)
++ return true;
++ if (check_add_overflow((int)sizeof(struct io_uring_recvmsg_out),
++ iomsg->namelen, &hdr))
++ return true;
++ if (check_add_overflow(hdr, (int)iomsg->controllen, &hdr))
++ return true;
++
++ return false;
++}
++
++#ifdef CONFIG_COMPAT
++static int __io_compat_msg_copy_hdr(struct io_kiocb *req,
++ struct io_async_msghdr *iomsg,
++ struct sockaddr __user **addr, int ddir)
++{
++ struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
++ struct compat_msghdr msg;
++ struct compat_iovec __user *uiov;
++ int ret;
++
++ if (copy_from_user(&msg, sr->umsg_compat, sizeof(msg)))
++ return -EFAULT;
++
++ ret = __get_compat_msghdr(&iomsg->msg, &msg, addr);
++ if (ret)
++ return ret;
++
++ uiov = compat_ptr(msg.msg_iov);
++ if (req->flags & REQ_F_BUFFER_SELECT) {
++ compat_ssize_t clen;
++
++ iomsg->free_iov = NULL;
++ if (msg.msg_iovlen == 0) {
++ sr->len = 0;
++ } else if (msg.msg_iovlen > 1) {
++ return -EINVAL;
++ } else {
++ if (!access_ok(uiov, sizeof(*uiov)))
++ return -EFAULT;
++ if (__get_user(clen, &uiov->iov_len))
++ return -EFAULT;
++ if (clen < 0)
++ return -EINVAL;
++ sr->len = clen;
++ }
++
++ if (ddir == ITER_DEST && req->flags & REQ_F_APOLL_MULTISHOT) {
++ iomsg->namelen = msg.msg_namelen;
++ iomsg->controllen = msg.msg_controllen;
++ if (io_recvmsg_multishot_overflow(iomsg))
++ return -EOVERFLOW;
++ }
++
++ return 0;
++ }
++
++ iomsg->free_iov = iomsg->fast_iov;
++ ret = __import_iovec(ddir, (struct iovec __user *)uiov, msg.msg_iovlen,
++ UIO_FASTIOV, &iomsg->free_iov,
++ &iomsg->msg.msg_iter, true);
++ if (unlikely(ret < 0))
++ return ret;
++
++ return 0;
++}
++#endif
++
++static int __io_msg_copy_hdr(struct io_kiocb *req, struct io_async_msghdr *iomsg,
++ struct sockaddr __user **addr, int ddir)
++{
++ struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
++ struct user_msghdr msg;
++ int ret;
++
++ if (copy_from_user(&msg, sr->umsg, sizeof(*sr->umsg)))
++ return -EFAULT;
++
++ ret = __copy_msghdr(&iomsg->msg, &msg, addr);
++ if (ret)
++ return ret;
++
++ if (req->flags & REQ_F_BUFFER_SELECT) {
++ if (msg.msg_iovlen == 0) {
++ sr->len = iomsg->fast_iov[0].iov_len = 0;
++ iomsg->fast_iov[0].iov_base = NULL;
++ iomsg->free_iov = NULL;
++ } else if (msg.msg_iovlen > 1) {
++ return -EINVAL;
++ } else {
++ if (copy_from_user(iomsg->fast_iov, msg.msg_iov,
++ sizeof(*msg.msg_iov)))
++ return -EFAULT;
++ sr->len = iomsg->fast_iov[0].iov_len;
++ iomsg->free_iov = NULL;
++ }
++
++ if (ddir == ITER_DEST && req->flags & REQ_F_APOLL_MULTISHOT) {
++ iomsg->namelen = msg.msg_namelen;
++ iomsg->controllen = msg.msg_controllen;
++ if (io_recvmsg_multishot_overflow(iomsg))
++ return -EOVERFLOW;
++ }
++
++ return 0;
++ }
++
++ iomsg->free_iov = iomsg->fast_iov;
++ ret = __import_iovec(ddir, msg.msg_iov, msg.msg_iovlen, UIO_FASTIOV,
++ &iomsg->free_iov, &iomsg->msg.msg_iter, false);
++ if (unlikely(ret < 0))
++ return ret;
++
++ return 0;
++}
++
++static int io_msg_copy_hdr(struct io_kiocb *req, struct io_async_msghdr *iomsg,
++ struct sockaddr __user **addr, int ddir)
++{
++ iomsg->msg.msg_name = &iomsg->addr;
++ iomsg->msg.msg_iter.nr_segs = 0;
++
++#ifdef CONFIG_COMPAT
++ if (req->ctx->compat)
++ return __io_compat_msg_copy_hdr(req, iomsg, addr, ddir);
++#endif
++
++ return __io_msg_copy_hdr(req, iomsg, addr, ddir);
++}
++
+ static int io_sendmsg_copy_hdr(struct io_kiocb *req,
+ struct io_async_msghdr *iomsg)
+ {
+ struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
+ int ret;
+
+- iomsg->msg.msg_name = &iomsg->addr;
+- iomsg->free_iov = iomsg->fast_iov;
+- ret = sendmsg_copy_msghdr(&iomsg->msg, sr->umsg, sr->msg_flags,
+- &iomsg->free_iov);
++ ret = io_msg_copy_hdr(req, iomsg, NULL, ITER_SOURCE);
++ if (ret)
++ return ret;
++
+ /* save msg_control as sys_sendmsg() overwrites it */
+ sr->msg_control = iomsg->msg.msg_control_user;
+ return ret;
+@@ -415,142 +549,21 @@ int io_send(struct io_kiocb *req, unsigned int issue_flags)
+ return IOU_OK;
+ }
+
+-static bool io_recvmsg_multishot_overflow(struct io_async_msghdr *iomsg)
+-{
+- int hdr;
+-
+- if (iomsg->namelen < 0)
+- return true;
+- if (check_add_overflow((int)sizeof(struct io_uring_recvmsg_out),
+- iomsg->namelen, &hdr))
+- return true;
+- if (check_add_overflow(hdr, (int)iomsg->controllen, &hdr))
+- return true;
+-
+- return false;
+-}
+-
+-static int __io_recvmsg_copy_hdr(struct io_kiocb *req,
+- struct io_async_msghdr *iomsg)
+-{
+- struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
+- struct user_msghdr msg;
+- int ret;
+-
+- if (copy_from_user(&msg, sr->umsg, sizeof(*sr->umsg)))
+- return -EFAULT;
+-
+- ret = __copy_msghdr(&iomsg->msg, &msg, &iomsg->uaddr);
+- if (ret)
+- return ret;
+-
+- if (req->flags & REQ_F_BUFFER_SELECT) {
+- if (msg.msg_iovlen == 0) {
+- sr->len = iomsg->fast_iov[0].iov_len = 0;
+- iomsg->fast_iov[0].iov_base = NULL;
+- iomsg->free_iov = NULL;
+- } else if (msg.msg_iovlen > 1) {
+- return -EINVAL;
+- } else {
+- if (copy_from_user(iomsg->fast_iov, msg.msg_iov, sizeof(*msg.msg_iov)))
+- return -EFAULT;
+- sr->len = iomsg->fast_iov[0].iov_len;
+- iomsg->free_iov = NULL;
+- }
+-
+- if (req->flags & REQ_F_APOLL_MULTISHOT) {
+- iomsg->namelen = msg.msg_namelen;
+- iomsg->controllen = msg.msg_controllen;
+- if (io_recvmsg_multishot_overflow(iomsg))
+- return -EOVERFLOW;
+- }
+- } else {
+- iomsg->free_iov = iomsg->fast_iov;
+- ret = __import_iovec(ITER_DEST, msg.msg_iov, msg.msg_iovlen, UIO_FASTIOV,
+- &iomsg->free_iov, &iomsg->msg.msg_iter,
+- false);
+- if (ret > 0)
+- ret = 0;
+- }
+-
+- return ret;
+-}
+-
+-#ifdef CONFIG_COMPAT
+-static int __io_compat_recvmsg_copy_hdr(struct io_kiocb *req,
+- struct io_async_msghdr *iomsg)
+-{
+- struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
+- struct compat_msghdr msg;
+- struct compat_iovec __user *uiov;
+- int ret;
+-
+- if (copy_from_user(&msg, sr->umsg_compat, sizeof(msg)))
+- return -EFAULT;
+-
+- ret = __get_compat_msghdr(&iomsg->msg, &msg, &iomsg->uaddr);
+- if (ret)
+- return ret;
+-
+- uiov = compat_ptr(msg.msg_iov);
+- if (req->flags & REQ_F_BUFFER_SELECT) {
+- compat_ssize_t clen;
+-
+- iomsg->free_iov = NULL;
+- if (msg.msg_iovlen == 0) {
+- sr->len = 0;
+- } else if (msg.msg_iovlen > 1) {
+- return -EINVAL;
+- } else {
+- if (!access_ok(uiov, sizeof(*uiov)))
+- return -EFAULT;
+- if (__get_user(clen, &uiov->iov_len))
+- return -EFAULT;
+- if (clen < 0)
+- return -EINVAL;
+- sr->len = clen;
+- }
+-
+- if (req->flags & REQ_F_APOLL_MULTISHOT) {
+- iomsg->namelen = msg.msg_namelen;
+- iomsg->controllen = msg.msg_controllen;
+- if (io_recvmsg_multishot_overflow(iomsg))
+- return -EOVERFLOW;
+- }
+- } else {
+- iomsg->free_iov = iomsg->fast_iov;
+- ret = __import_iovec(ITER_DEST, (struct iovec __user *)uiov, msg.msg_iovlen,
+- UIO_FASTIOV, &iomsg->free_iov,
+- &iomsg->msg.msg_iter, true);
+- if (ret < 0)
+- return ret;
+- }
+-
+- return 0;
+-}
+-#endif
+-
+ static int io_recvmsg_copy_hdr(struct io_kiocb *req,
+ struct io_async_msghdr *iomsg)
+ {
+- iomsg->msg.msg_name = &iomsg->addr;
+- iomsg->msg.msg_iter.nr_segs = 0;
+-
+-#ifdef CONFIG_COMPAT
+- if (req->ctx->compat)
+- return __io_compat_recvmsg_copy_hdr(req, iomsg);
+-#endif
+-
+- return __io_recvmsg_copy_hdr(req, iomsg);
++ return io_msg_copy_hdr(req, iomsg, &iomsg->uaddr, ITER_DEST);
+ }
+
+ int io_recvmsg_prep_async(struct io_kiocb *req)
+ {
++ struct io_async_msghdr *iomsg;
+ int ret;
+
+ if (!io_msg_alloc_async_prep(req))
+ return -ENOMEM;
+- ret = io_recvmsg_copy_hdr(req, req->async_data);
++ iomsg = req->async_data;
++ ret = io_recvmsg_copy_hdr(req, iomsg);
+ if (!ret)
+ req->flags |= REQ_F_NEED_CLEANUP;
+ return ret;
+--
+2.43.0
+
--- /dev/null
+From 425c957759ade58d781383ed71bbb4480bbc805f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jan 2024 17:34:00 -0600
+Subject: iommu/amd: Mark interrupt as managed
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit 0feda94c868d396fac3b3cb14089d2d989a07c72 ]
+
+On many systems that have an AMD IOMMU the following sequence of
+warnings is observed during bootup.
+
+```
+pci 0000:00:00.2 can't derive routing for PCI INT A
+pci 0000:00:00.2: PCI INT A: not connected
+```
+
+This series of events happens because of the IOMMU initialization
+sequence order and the lack of _PRT entries for the IOMMU.
+
+During initialization the IOMMU driver first enables the PCI device
+using pci_enable_device(). This will call acpi_pci_irq_enable()
+which will check if the interrupt is declared in a PCI routing table
+(_PRT) entry. According to the PCI spec [1] these routing entries
+are only required under PCI root bridges:
+ The _PRT object is required under all PCI root bridges
+
+The IOMMU is directly connected to the root complex, so there is no
+parent bridge to look for a _PRT entry. The first warning is emitted
+since no entry could be found in the hierarchy. The second warning is
+then emitted because the interrupt hasn't yet been configured to any
+value. The pin was configured in pci_read_irq() but the byte in
+PCI_INTERRUPT_LINE return 0xff which means "Unknown".
+
+After that sequence of events pci_enable_msi() is called and this
+will allocate an interrupt.
+
+That is both of these warnings are totally harmless because the IOMMU
+uses MSI for interrupts. To avoid even trying to probe for a _PRT
+entry mark the IOMMU as IRQ managed. This avoids both warnings.
+
+Link: https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/06_Device_Configuration/Device_Configuration.html?highlight=_prt#prt-pci-routing-table [1]
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Fixes: cffe0a2b5a34 ("x86, irq: Keep balance of IOAPIC pin reference count")
+Reviewed-by: Vasant Hegde <vasant.hegde@amd.com>
+Link: https://lore.kernel.org/r/20240122233400.1802-1-mario.limonciello@amd.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/amd/init.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
+index f6e64c9858021..cc94ac6662339 100644
+--- a/drivers/iommu/amd/init.c
++++ b/drivers/iommu/amd/init.c
+@@ -2047,6 +2047,9 @@ static int __init iommu_init_pci(struct amd_iommu *iommu)
+ /* Prevent binding other PCI device drivers to IOMMU devices */
+ iommu->dev->match_driver = false;
+
++ /* ACPI _PRT won't have an IRQ for IOMMU */
++ iommu->dev->irq_managed = 1;
++
+ pci_read_config_dword(iommu->dev, cap_ptr + MMIO_CAP_HDR_OFFSET,
+ &iommu->cap);
+
+--
+2.43.0
+
--- /dev/null
+From fae7ae35194dddc7fd7c66fa2fa5c1eaf9fea898 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 20:44:19 +0100
+Subject: iommu: Fix compilation without CONFIG_IOMMU_INTEL
+
+From: Bert Karwatzki <spasswolf@web.de>
+
+[ Upstream commit 70bad345e622c23bb530016925c936ab04a646ac ]
+
+When the kernel is comiled with CONFIG_IRQ_REMAP=y but without
+CONFIG_IOMMU_INTEL compilation fails since commit def054b01a8678 with an
+undefined reference to device_rbtree_find(). This patch makes sure that
+intel specific code is only compiled with CONFIG_IOMMU_INTEL=y.
+
+Signed-off-by: Bert Karwatzki <spasswolf@web.de>
+Fixes: 80a9b50c0b9e ("iommu/vt-d: Improve ITE fault handling if target device isn't present")
+Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
+Link: https://lore.kernel.org/r/20240307194419.15801-1-spasswolf@web.de
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/Kconfig | 2 +-
+ drivers/iommu/intel/Makefile | 2 ++
+ drivers/iommu/irq_remapping.c | 3 ++-
+ 3 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
+index dc5f7a156ff5e..dc19e7fb07cfe 100644
+--- a/drivers/iommu/Kconfig
++++ b/drivers/iommu/Kconfig
+@@ -192,7 +192,7 @@ source "drivers/iommu/intel/Kconfig"
+ config IRQ_REMAP
+ bool "Support for Interrupt Remapping"
+ depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI
+- select DMAR_TABLE
++ select DMAR_TABLE if INTEL_IOMMU
+ help
+ Supports Interrupt remapping for IO-APIC and MSI devices.
+ To use x2apic mode in the CPU's which support x2APIC enhancements or
+diff --git a/drivers/iommu/intel/Makefile b/drivers/iommu/intel/Makefile
+index 7af3b8a4f2a00..29d26a4371327 100644
+--- a/drivers/iommu/intel/Makefile
++++ b/drivers/iommu/intel/Makefile
+@@ -5,5 +5,7 @@ obj-$(CONFIG_DMAR_TABLE) += trace.o cap_audit.o
+ obj-$(CONFIG_DMAR_PERF) += perf.o
+ obj-$(CONFIG_INTEL_IOMMU_DEBUGFS) += debugfs.o
+ obj-$(CONFIG_INTEL_IOMMU_SVM) += svm.o
++ifdef CONFIG_INTEL_IOMMU
+ obj-$(CONFIG_IRQ_REMAP) += irq_remapping.o
++endif
+ obj-$(CONFIG_INTEL_IOMMU_PERF_EVENTS) += perfmon.o
+diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
+index 83314b9d8f38b..ee59647c20501 100644
+--- a/drivers/iommu/irq_remapping.c
++++ b/drivers/iommu/irq_remapping.c
+@@ -99,7 +99,8 @@ int __init irq_remapping_prepare(void)
+ if (disable_irq_remap)
+ return -ENOSYS;
+
+- if (intel_irq_remap_ops.prepare() == 0)
++ if (IS_ENABLED(CONFIG_INTEL_IOMMU) &&
++ intel_irq_remap_ops.prepare() == 0)
+ remap_ops = &intel_irq_remap_ops;
+ else if (IS_ENABLED(CONFIG_AMD_IOMMU) &&
+ amd_iommu_irq_ops.prepare() == 0)
+--
+2.43.0
+
--- /dev/null
+From 5c87da2d8755f445682d5ce7ff0d8d4f3ea31199 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 20:21:15 +0800
+Subject: iommu/vt-d: Don't issue ATS Invalidation request when device is
+ disconnected
+
+From: Ethan Zhao <haifeng.zhao@linux.intel.com>
+
+[ Upstream commit 4fc82cd907ac075648789cc3a00877778aa1838b ]
+
+For those endpoint devices connect to system via hotplug capable ports,
+users could request a hot reset to the device by flapping device's link
+through setting the slot's link control register, as pciehp_ist() DLLSC
+interrupt sequence response, pciehp will unload the device driver and
+then power it off. thus cause an IOMMU device-TLB invalidation (Intel
+VT-d spec, or ATS Invalidation in PCIe spec r6.1) request for non-existence
+target device to be sent and deadly loop to retry that request after ITE
+fault triggered in interrupt context.
+
+That would cause following continuous hard lockup warning and system hang
+
+[ 4211.433662] pcieport 0000:17:01.0: pciehp: Slot(108): Link Down
+[ 4211.433664] pcieport 0000:17:01.0: pciehp: Slot(108): Card not present
+[ 4223.822591] NMI watchdog: Watchdog detected hard LOCKUP on cpu 144
+[ 4223.822622] CPU: 144 PID: 1422 Comm: irq/57-pciehp Kdump: loaded Tainted: G S
+ OE kernel version xxxx
+[ 4223.822623] Hardware name: vendorname xxxx 666-106,
+BIOS 01.01.02.03.01 05/15/2023
+[ 4223.822623] RIP: 0010:qi_submit_sync+0x2c0/0x490
+[ 4223.822624] Code: 48 be 00 00 00 00 00 08 00 00 49 85 74 24 20 0f 95 c1 48 8b
+ 57 10 83 c1 04 83 3c 1a 03 0f 84 a2 01 00 00 49 8b 04 24 8b 70 34 <40> f6 c6 1
+0 74 17 49 8b 04 24 8b 80 80 00 00 00 89 c2 d3 fa 41 39
+[ 4223.822624] RSP: 0018:ffffc4f074f0bbb8 EFLAGS: 00000093
+[ 4223.822625] RAX: ffffc4f040059000 RBX: 0000000000000014 RCX: 0000000000000005
+[ 4223.822625] RDX: ffff9f3841315800 RSI: 0000000000000000 RDI: ffff9f38401a8340
+[ 4223.822625] RBP: ffff9f38401a8340 R08: ffffc4f074f0bc00 R09: 0000000000000000
+[ 4223.822626] R10: 0000000000000010 R11: 0000000000000018 R12: ffff9f384005e200
+[ 4223.822626] R13: 0000000000000004 R14: 0000000000000046 R15: 0000000000000004
+[ 4223.822626] FS: 0000000000000000(0000) GS:ffffa237ae400000(0000)
+knlGS:0000000000000000
+[ 4223.822627] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 4223.822627] CR2: 00007ffe86515d80 CR3: 000002fd3000a001 CR4: 0000000000770ee0
+[ 4223.822627] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[ 4223.822628] DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400
+[ 4223.822628] PKRU: 55555554
+[ 4223.822628] Call Trace:
+[ 4223.822628] qi_flush_dev_iotlb+0xb1/0xd0
+[ 4223.822628] __dmar_remove_one_dev_info+0x224/0x250
+[ 4223.822629] dmar_remove_one_dev_info+0x3e/0x50
+[ 4223.822629] intel_iommu_release_device+0x1f/0x30
+[ 4223.822629] iommu_release_device+0x33/0x60
+[ 4223.822629] iommu_bus_notifier+0x7f/0x90
+[ 4223.822630] blocking_notifier_call_chain+0x60/0x90
+[ 4223.822630] device_del+0x2e5/0x420
+[ 4223.822630] pci_remove_bus_device+0x70/0x110
+[ 4223.822630] pciehp_unconfigure_device+0x7c/0x130
+[ 4223.822631] pciehp_disable_slot+0x6b/0x100
+[ 4223.822631] pciehp_handle_presence_or_link_change+0xd8/0x320
+[ 4223.822631] pciehp_ist+0x176/0x180
+[ 4223.822631] ? irq_finalize_oneshot.part.50+0x110/0x110
+[ 4223.822632] irq_thread_fn+0x19/0x50
+[ 4223.822632] irq_thread+0x104/0x190
+[ 4223.822632] ? irq_forced_thread_fn+0x90/0x90
+[ 4223.822632] ? irq_thread_check_affinity+0xe0/0xe0
+[ 4223.822633] kthread+0x114/0x130
+[ 4223.822633] ? __kthread_cancel_work+0x40/0x40
+[ 4223.822633] ret_from_fork+0x1f/0x30
+[ 4223.822633] Kernel panic - not syncing: Hard LOCKUP
+[ 4223.822634] CPU: 144 PID: 1422 Comm: irq/57-pciehp Kdump: loaded Tainted: G S
+ OE kernel version xxxx
+[ 4223.822634] Hardware name: vendorname xxxx 666-106,
+BIOS 01.01.02.03.01 05/15/2023
+[ 4223.822634] Call Trace:
+[ 4223.822634] <NMI>
+[ 4223.822635] dump_stack+0x6d/0x88
+[ 4223.822635] panic+0x101/0x2d0
+[ 4223.822635] ? ret_from_fork+0x11/0x30
+[ 4223.822635] nmi_panic.cold.14+0xc/0xc
+[ 4223.822636] watchdog_overflow_callback.cold.8+0x6d/0x81
+[ 4223.822636] __perf_event_overflow+0x4f/0xf0
+[ 4223.822636] handle_pmi_common+0x1ef/0x290
+[ 4223.822636] ? __set_pte_vaddr+0x28/0x40
+[ 4223.822637] ? flush_tlb_one_kernel+0xa/0x20
+[ 4223.822637] ? __native_set_fixmap+0x24/0x30
+[ 4223.822637] ? ghes_copy_tofrom_phys+0x70/0x100
+[ 4223.822637] ? __ghes_peek_estatus.isra.16+0x49/0xa0
+[ 4223.822637] intel_pmu_handle_irq+0xba/0x2b0
+[ 4223.822638] perf_event_nmi_handler+0x24/0x40
+[ 4223.822638] nmi_handle+0x4d/0xf0
+[ 4223.822638] default_do_nmi+0x49/0x100
+[ 4223.822638] exc_nmi+0x134/0x180
+[ 4223.822639] end_repeat_nmi+0x16/0x67
+[ 4223.822639] RIP: 0010:qi_submit_sync+0x2c0/0x490
+[ 4223.822639] Code: 48 be 00 00 00 00 00 08 00 00 49 85 74 24 20 0f 95 c1 48 8b
+ 57 10 83 c1 04 83 3c 1a 03 0f 84 a2 01 00 00 49 8b 04 24 8b 70 34 <40> f6 c6 10
+ 74 17 49 8b 04 24 8b 80 80 00 00 00 89 c2 d3 fa 41 39
+[ 4223.822640] RSP: 0018:ffffc4f074f0bbb8 EFLAGS: 00000093
+[ 4223.822640] RAX: ffffc4f040059000 RBX: 0000000000000014 RCX: 0000000000000005
+[ 4223.822640] RDX: ffff9f3841315800 RSI: 0000000000000000 RDI: ffff9f38401a8340
+[ 4223.822641] RBP: ffff9f38401a8340 R08: ffffc4f074f0bc00 R09: 0000000000000000
+[ 4223.822641] R10: 0000000000000010 R11: 0000000000000018 R12: ffff9f384005e200
+[ 4223.822641] R13: 0000000000000004 R14: 0000000000000046 R15: 0000000000000004
+[ 4223.822641] ? qi_submit_sync+0x2c0/0x490
+[ 4223.822642] ? qi_submit_sync+0x2c0/0x490
+[ 4223.822642] </NMI>
+[ 4223.822642] qi_flush_dev_iotlb+0xb1/0xd0
+[ 4223.822642] __dmar_remove_one_dev_info+0x224/0x250
+[ 4223.822643] dmar_remove_one_dev_info+0x3e/0x50
+[ 4223.822643] intel_iommu_release_device+0x1f/0x30
+[ 4223.822643] iommu_release_device+0x33/0x60
+[ 4223.822643] iommu_bus_notifier+0x7f/0x90
+[ 4223.822644] blocking_notifier_call_chain+0x60/0x90
+[ 4223.822644] device_del+0x2e5/0x420
+[ 4223.822644] pci_remove_bus_device+0x70/0x110
+[ 4223.822644] pciehp_unconfigure_device+0x7c/0x130
+[ 4223.822644] pciehp_disable_slot+0x6b/0x100
+[ 4223.822645] pciehp_handle_presence_or_link_change+0xd8/0x320
+[ 4223.822645] pciehp_ist+0x176/0x180
+[ 4223.822645] ? irq_finalize_oneshot.part.50+0x110/0x110
+[ 4223.822645] irq_thread_fn+0x19/0x50
+[ 4223.822646] irq_thread+0x104/0x190
+[ 4223.822646] ? irq_forced_thread_fn+0x90/0x90
+[ 4223.822646] ? irq_thread_check_affinity+0xe0/0xe0
+[ 4223.822646] kthread+0x114/0x130
+[ 4223.822647] ? __kthread_cancel_work+0x40/0x40
+[ 4223.822647] ret_from_fork+0x1f/0x30
+[ 4223.822647] Kernel Offset: 0x6400000 from 0xffffffff81000000 (relocation
+range: 0xffffffff80000000-0xffffffffbfffffff)
+
+Such issue could be triggered by all kinds of regular surprise removal
+hotplug operation. like:
+
+1. pull EP(endpoint device) out directly.
+2. turn off EP's power.
+3. bring the link down.
+etc.
+
+this patch aims to work for regular safe removal and surprise removal
+unplug. these hot unplug handling process could be optimized for fix the
+ATS Invalidation hang issue by calling pci_dev_is_disconnected() in
+function devtlb_invalidation_with_pasid() to check target device state to
+avoid sending meaningless ATS Invalidation request to iommu when device is
+gone. (see IMPLEMENTATION NOTE in PCIe spec r6.1 section 10.3.1)
+
+For safe removal, device wouldn't be removed until the whole software
+handling process is done, it wouldn't trigger the hard lock up issue
+caused by too long ATS Invalidation timeout wait. In safe removal path,
+device state isn't set to pci_channel_io_perm_failure in
+pciehp_unconfigure_device() by checking 'presence' parameter, calling
+pci_dev_is_disconnected() in devtlb_invalidation_with_pasid() will return
+false there, wouldn't break the function.
+
+For surprise removal, device state is set to pci_channel_io_perm_failure in
+pciehp_unconfigure_device(), means device is already gone (disconnected)
+call pci_dev_is_disconnected() in devtlb_invalidation_with_pasid() will
+return true to break the function not to send ATS Invalidation request to
+the disconnected device blindly, thus avoid to trigger further ITE fault,
+and ITE fault will block all invalidation request to be handled.
+furthermore retry the timeout request could trigger hard lockup.
+
+safe removal (present) & surprise removal (not present)
+
+pciehp_ist()
+ pciehp_handle_presence_or_link_change()
+ pciehp_disable_slot()
+ remove_board()
+ pciehp_unconfigure_device(presence) {
+ if (!presence)
+ pci_walk_bus(parent, pci_dev_set_disconnected, NULL);
+ }
+
+this patch works for regular safe removal and surprise removal of ATS
+capable endpoint on PCIe switch downstream ports.
+
+Fixes: 6f7db75e1c46 ("iommu/vt-d: Add second level page table interface")
+Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
+Tested-by: Haorong Ye <yehaorong@bytedance.com>
+Signed-off-by: Ethan Zhao <haifeng.zhao@linux.intel.com>
+Link: https://lore.kernel.org/r/20240301080727.3529832-3-haifeng.zhao@linux.intel.com
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/intel/pasid.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
+index 3f03039e5cce5..32432d82d7744 100644
+--- a/drivers/iommu/intel/pasid.c
++++ b/drivers/iommu/intel/pasid.c
+@@ -435,6 +435,9 @@ devtlb_invalidation_with_pasid(struct intel_iommu *iommu,
+ if (!info || !info->ats_enabled)
+ return;
+
++ if (pci_dev_is_disconnected(to_pci_dev(dev)))
++ return;
++
+ sid = info->bus << 8 | info->devfn;
+ qdep = info->ats_qdep;
+ pfsid = info->pfsid;
+--
+2.43.0
+
--- /dev/null
+From a9937ca229f60f3b7ac7887f520814d34901c568 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Jan 2023 15:37:35 +0800
+Subject: iommu/vt-d: Retrieve IOMMU perfmon capability information
+
+From: Kan Liang <kan.liang@linux.intel.com>
+
+[ Upstream commit a6a5006dad572a53b5df3f47e1471d207ae9ba49 ]
+
+The performance monitoring infrastructure, perfmon, is to support
+collection of information about key events occurring during operation of
+the remapping hardware, to aid performance tuning and debug. Each
+remapping hardware unit has capability registers that indicate support
+for performance monitoring features and enumerate the capabilities.
+
+Add alloc_iommu_pmu() to retrieve IOMMU perfmon capability information
+for each iommu unit. The information is stored in the iommu->pmu data
+structure. Capability registers are read-only, so it's safe to prefetch
+and store them in the pmu structure. This could avoid unnecessary VMEXIT
+when this code is running in the virtualization environment.
+
+Add free_iommu_pmu() to free the saved capability information when
+freeing the iommu unit.
+
+Add a kernel config option for the IOMMU perfmon feature. Unless a user
+explicitly uses the perf tool to monitor the IOMMU perfmon event, there
+isn't any impact for the existing IOMMU. Enable it by default.
+
+Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
+Link: https://lore.kernel.org/r/20230128200428.1459118-3-kan.liang@linux.intel.com
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Stable-dep-of: 70bad345e622 ("iommu: Fix compilation without CONFIG_IOMMU_INTEL")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/intel/Kconfig | 11 +++
+ drivers/iommu/intel/Makefile | 1 +
+ drivers/iommu/intel/dmar.c | 7 ++
+ drivers/iommu/intel/iommu.h | 43 ++++++++-
+ drivers/iommu/intel/perfmon.c | 172 ++++++++++++++++++++++++++++++++++
+ drivers/iommu/intel/perfmon.h | 40 ++++++++
+ 6 files changed, 273 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/iommu/intel/perfmon.c
+ create mode 100644 drivers/iommu/intel/perfmon.h
+
+diff --git a/drivers/iommu/intel/Kconfig b/drivers/iommu/intel/Kconfig
+index b7dff5092fd21..12e1e90fdae13 100644
+--- a/drivers/iommu/intel/Kconfig
++++ b/drivers/iommu/intel/Kconfig
+@@ -96,4 +96,15 @@ config INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON
+ passing intel_iommu=sm_on to the kernel. If not sure, please use
+ the default value.
+
++config INTEL_IOMMU_PERF_EVENTS
++ def_bool y
++ bool "Intel IOMMU performance events"
++ depends on INTEL_IOMMU && PERF_EVENTS
++ help
++ Selecting this option will enable the performance monitoring
++ infrastructure in the Intel IOMMU. It collects information about
++ key events occurring during operation of the remapping hardware,
++ to aid performance tuning and debug. These are available on modern
++ processors which support Intel VT-d 4.0 and later.
++
+ endif # INTEL_IOMMU
+diff --git a/drivers/iommu/intel/Makefile b/drivers/iommu/intel/Makefile
+index fa0dae16441cb..7af3b8a4f2a00 100644
+--- a/drivers/iommu/intel/Makefile
++++ b/drivers/iommu/intel/Makefile
+@@ -6,3 +6,4 @@ obj-$(CONFIG_DMAR_PERF) += perf.o
+ obj-$(CONFIG_INTEL_IOMMU_DEBUGFS) += debugfs.o
+ obj-$(CONFIG_INTEL_IOMMU_SVM) += svm.o
+ obj-$(CONFIG_IRQ_REMAP) += irq_remapping.o
++obj-$(CONFIG_INTEL_IOMMU_PERF_EVENTS) += perfmon.o
+diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
+index 418af1db0192d..4759f79ad7b94 100644
+--- a/drivers/iommu/intel/dmar.c
++++ b/drivers/iommu/intel/dmar.c
+@@ -34,6 +34,7 @@
+ #include "../irq_remapping.h"
+ #include "perf.h"
+ #include "trace.h"
++#include "perfmon.h"
+
+ typedef int (*dmar_res_handler_t)(struct acpi_dmar_header *, void *);
+ struct dmar_res_callback {
+@@ -1104,6 +1105,9 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
+ if (sts & DMA_GSTS_QIES)
+ iommu->gcmd |= DMA_GCMD_QIE;
+
++ if (alloc_iommu_pmu(iommu))
++ pr_debug("Cannot alloc PMU for iommu (seq_id = %d)\n", iommu->seq_id);
++
+ raw_spin_lock_init(&iommu->register_lock);
+
+ /*
+@@ -1131,6 +1135,7 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
+ err_sysfs:
+ iommu_device_sysfs_remove(&iommu->iommu);
+ err_unmap:
++ free_iommu_pmu(iommu);
+ unmap_iommu(iommu);
+ error_free_seq_id:
+ ida_free(&dmar_seq_ids, iommu->seq_id);
+@@ -1146,6 +1151,8 @@ static void free_iommu(struct intel_iommu *iommu)
+ iommu_device_sysfs_remove(&iommu->iommu);
+ }
+
++ free_iommu_pmu(iommu);
++
+ if (iommu->irq) {
+ if (iommu->pr_irq) {
+ free_irq(iommu->pr_irq, iommu);
+diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h
+index c99cb715bd9a2..c1348bedab3b3 100644
+--- a/drivers/iommu/intel/iommu.h
++++ b/drivers/iommu/intel/iommu.h
+@@ -125,6 +125,11 @@
+ #define DMAR_MTRR_PHYSMASK8_REG 0x208
+ #define DMAR_MTRR_PHYSBASE9_REG 0x210
+ #define DMAR_MTRR_PHYSMASK9_REG 0x218
++#define DMAR_PERFCAP_REG 0x300
++#define DMAR_PERFCFGOFF_REG 0x310
++#define DMAR_PERFOVFOFF_REG 0x318
++#define DMAR_PERFCNTROFF_REG 0x31c
++#define DMAR_PERFEVNTCAP_REG 0x380
+ #define DMAR_VCCAP_REG 0xe30 /* Virtual command capability register */
+ #define DMAR_VCMD_REG 0xe00 /* Virtual command register */
+ #define DMAR_VCRSP_REG 0xe10 /* Virtual command response register */
+@@ -148,6 +153,7 @@
+ */
+ #define cap_esrtps(c) (((c) >> 63) & 1)
+ #define cap_esirtps(c) (((c) >> 62) & 1)
++#define cap_ecmds(c) (((c) >> 61) & 1)
+ #define cap_fl5lp_support(c) (((c) >> 60) & 1)
+ #define cap_pi_support(c) (((c) >> 59) & 1)
+ #define cap_fl1gp_support(c) (((c) >> 56) & 1)
+@@ -179,7 +185,8 @@
+ * Extended Capability Register
+ */
+
+-#define ecap_rps(e) (((e) >> 49) & 0x1)
++#define ecap_pms(e) (((e) >> 51) & 0x1)
++#define ecap_rps(e) (((e) >> 49) & 0x1)
+ #define ecap_smpwc(e) (((e) >> 48) & 0x1)
+ #define ecap_flts(e) (((e) >> 47) & 0x1)
+ #define ecap_slts(e) (((e) >> 46) & 0x1)
+@@ -210,6 +217,22 @@
+ #define ecap_max_handle_mask(e) (((e) >> 20) & 0xf)
+ #define ecap_sc_support(e) (((e) >> 7) & 0x1) /* Snooping Control */
+
++/*
++ * Decoding Perf Capability Register
++ */
++#define pcap_num_cntr(p) ((p) & 0xffff)
++#define pcap_cntr_width(p) (((p) >> 16) & 0x7f)
++#define pcap_num_event_group(p) (((p) >> 24) & 0x1f)
++#define pcap_filters_mask(p) (((p) >> 32) & 0x1f)
++#define pcap_interrupt(p) (((p) >> 50) & 0x1)
++/* The counter stride is calculated as 2 ^ (x+10) bytes */
++#define pcap_cntr_stride(p) (1ULL << ((((p) >> 52) & 0x7) + 10))
++
++/*
++ * Decoding Perf Event Capability Register
++ */
++#define pecap_es(p) ((p) & 0xfffffff)
++
+ /* Virtual command interface capability */
+ #define vccap_pasid(v) (((v) & DMA_VCS_PAS)) /* PASID allocation */
+
+@@ -561,6 +584,22 @@ struct dmar_domain {
+ iommu core */
+ };
+
++struct iommu_pmu {
++ struct intel_iommu *iommu;
++ u32 num_cntr; /* Number of counters */
++ u32 num_eg; /* Number of event group */
++ u32 cntr_width; /* Counter width */
++ u32 cntr_stride; /* Counter Stride */
++ u32 filter; /* Bitmask of filter support */
++ void __iomem *base; /* the PerfMon base address */
++ void __iomem *cfg_reg; /* counter configuration base address */
++ void __iomem *cntr_reg; /* counter 0 address*/
++ void __iomem *overflow; /* overflow status register */
++
++ u64 *evcap; /* Indicates all supported events */
++ u32 **cntr_evcap; /* Supported events of each counter. */
++};
++
+ struct intel_iommu {
+ void __iomem *reg; /* Pointer to hardware regs, virtual addr */
+ u64 reg_phys; /* physical address of hw register set */
+@@ -608,6 +647,8 @@ struct intel_iommu {
+
+ struct dmar_drhd_unit *drhd;
+ void *perf_statistic;
++
++ struct iommu_pmu *pmu;
+ };
+
+ /* PCI domain-device relationship */
+diff --git a/drivers/iommu/intel/perfmon.c b/drivers/iommu/intel/perfmon.c
+new file mode 100644
+index 0000000000000..db5791a544551
+--- /dev/null
++++ b/drivers/iommu/intel/perfmon.c
+@@ -0,0 +1,172 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Support Intel IOMMU PerfMon
++ * Copyright(c) 2023 Intel Corporation.
++ */
++#define pr_fmt(fmt) "DMAR: " fmt
++#define dev_fmt(fmt) pr_fmt(fmt)
++
++#include <linux/dmar.h>
++#include "iommu.h"
++#include "perfmon.h"
++
++static inline void __iomem *
++get_perf_reg_address(struct intel_iommu *iommu, u32 offset)
++{
++ u32 off = dmar_readl(iommu->reg + offset);
++
++ return iommu->reg + off;
++}
++
++int alloc_iommu_pmu(struct intel_iommu *iommu)
++{
++ struct iommu_pmu *iommu_pmu;
++ int i, j, ret;
++ u64 perfcap;
++ u32 cap;
++
++ if (!ecap_pms(iommu->ecap))
++ return 0;
++
++ /* The IOMMU PMU requires the ECMD support as well */
++ if (!cap_ecmds(iommu->cap))
++ return -ENODEV;
++
++ perfcap = dmar_readq(iommu->reg + DMAR_PERFCAP_REG);
++ /* The performance monitoring is not supported. */
++ if (!perfcap)
++ return -ENODEV;
++
++ /* Sanity check for the number of the counters and event groups */
++ if (!pcap_num_cntr(perfcap) || !pcap_num_event_group(perfcap))
++ return -ENODEV;
++
++ /* The interrupt on overflow is required */
++ if (!pcap_interrupt(perfcap))
++ return -ENODEV;
++
++ iommu_pmu = kzalloc(sizeof(*iommu_pmu), GFP_KERNEL);
++ if (!iommu_pmu)
++ return -ENOMEM;
++
++ iommu_pmu->num_cntr = pcap_num_cntr(perfcap);
++ iommu_pmu->cntr_width = pcap_cntr_width(perfcap);
++ iommu_pmu->filter = pcap_filters_mask(perfcap);
++ iommu_pmu->cntr_stride = pcap_cntr_stride(perfcap);
++ iommu_pmu->num_eg = pcap_num_event_group(perfcap);
++
++ iommu_pmu->evcap = kcalloc(iommu_pmu->num_eg, sizeof(u64), GFP_KERNEL);
++ if (!iommu_pmu->evcap) {
++ ret = -ENOMEM;
++ goto free_pmu;
++ }
++
++ /* Parse event group capabilities */
++ for (i = 0; i < iommu_pmu->num_eg; i++) {
++ u64 pcap;
++
++ pcap = dmar_readq(iommu->reg + DMAR_PERFEVNTCAP_REG +
++ i * IOMMU_PMU_CAP_REGS_STEP);
++ iommu_pmu->evcap[i] = pecap_es(pcap);
++ }
++
++ iommu_pmu->cntr_evcap = kcalloc(iommu_pmu->num_cntr, sizeof(u32 *), GFP_KERNEL);
++ if (!iommu_pmu->cntr_evcap) {
++ ret = -ENOMEM;
++ goto free_pmu_evcap;
++ }
++ for (i = 0; i < iommu_pmu->num_cntr; i++) {
++ iommu_pmu->cntr_evcap[i] = kcalloc(iommu_pmu->num_eg, sizeof(u32), GFP_KERNEL);
++ if (!iommu_pmu->cntr_evcap[i]) {
++ ret = -ENOMEM;
++ goto free_pmu_cntr_evcap;
++ }
++ /*
++ * Set to the global capabilities, will adjust according
++ * to per-counter capabilities later.
++ */
++ for (j = 0; j < iommu_pmu->num_eg; j++)
++ iommu_pmu->cntr_evcap[i][j] = (u32)iommu_pmu->evcap[j];
++ }
++
++ iommu_pmu->cfg_reg = get_perf_reg_address(iommu, DMAR_PERFCFGOFF_REG);
++ iommu_pmu->cntr_reg = get_perf_reg_address(iommu, DMAR_PERFCNTROFF_REG);
++ iommu_pmu->overflow = get_perf_reg_address(iommu, DMAR_PERFOVFOFF_REG);
++
++ /*
++ * Check per-counter capabilities. All counters should have the
++ * same capabilities on Interrupt on Overflow Support and Counter
++ * Width.
++ */
++ for (i = 0; i < iommu_pmu->num_cntr; i++) {
++ cap = dmar_readl(iommu_pmu->cfg_reg +
++ i * IOMMU_PMU_CFG_OFFSET +
++ IOMMU_PMU_CFG_CNTRCAP_OFFSET);
++ if (!iommu_cntrcap_pcc(cap))
++ continue;
++
++ /*
++ * It's possible that some counters have a different
++ * capability because of e.g., HW bug. Check the corner
++ * case here and simply drop those counters.
++ */
++ if ((iommu_cntrcap_cw(cap) != iommu_pmu->cntr_width) ||
++ !iommu_cntrcap_ios(cap)) {
++ iommu_pmu->num_cntr = i;
++ pr_warn("PMU counter capability inconsistent, counter number reduced to %d\n",
++ iommu_pmu->num_cntr);
++ }
++
++ /* Clear the pre-defined events group */
++ for (j = 0; j < iommu_pmu->num_eg; j++)
++ iommu_pmu->cntr_evcap[i][j] = 0;
++
++ /* Override with per-counter event capabilities */
++ for (j = 0; j < iommu_cntrcap_egcnt(cap); j++) {
++ cap = dmar_readl(iommu_pmu->cfg_reg + i * IOMMU_PMU_CFG_OFFSET +
++ IOMMU_PMU_CFG_CNTREVCAP_OFFSET +
++ (j * IOMMU_PMU_OFF_REGS_STEP));
++ iommu_pmu->cntr_evcap[i][iommu_event_group(cap)] = iommu_event_select(cap);
++ /*
++ * Some events may only be supported by a specific counter.
++ * Track them in the evcap as well.
++ */
++ iommu_pmu->evcap[iommu_event_group(cap)] |= iommu_event_select(cap);
++ }
++ }
++
++ iommu_pmu->iommu = iommu;
++ iommu->pmu = iommu_pmu;
++
++ return 0;
++
++free_pmu_cntr_evcap:
++ for (i = 0; i < iommu_pmu->num_cntr; i++)
++ kfree(iommu_pmu->cntr_evcap[i]);
++ kfree(iommu_pmu->cntr_evcap);
++free_pmu_evcap:
++ kfree(iommu_pmu->evcap);
++free_pmu:
++ kfree(iommu_pmu);
++
++ return ret;
++}
++
++void free_iommu_pmu(struct intel_iommu *iommu)
++{
++ struct iommu_pmu *iommu_pmu = iommu->pmu;
++
++ if (!iommu_pmu)
++ return;
++
++ if (iommu_pmu->evcap) {
++ int i;
++
++ for (i = 0; i < iommu_pmu->num_cntr; i++)
++ kfree(iommu_pmu->cntr_evcap[i]);
++ kfree(iommu_pmu->cntr_evcap);
++ }
++ kfree(iommu_pmu->evcap);
++ kfree(iommu_pmu);
++ iommu->pmu = NULL;
++}
+diff --git a/drivers/iommu/intel/perfmon.h b/drivers/iommu/intel/perfmon.h
+new file mode 100644
+index 0000000000000..4b0d9c1fea6ff
+--- /dev/null
++++ b/drivers/iommu/intel/perfmon.h
+@@ -0,0 +1,40 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++
++/*
++ * PERFCFGOFF_REG, PERFFRZOFF_REG
++ * PERFOVFOFF_REG, PERFCNTROFF_REG
++ */
++#define IOMMU_PMU_NUM_OFF_REGS 4
++#define IOMMU_PMU_OFF_REGS_STEP 4
++
++#define IOMMU_PMU_CFG_OFFSET 0x100
++#define IOMMU_PMU_CFG_CNTRCAP_OFFSET 0x80
++#define IOMMU_PMU_CFG_CNTREVCAP_OFFSET 0x84
++#define IOMMU_PMU_CFG_SIZE 0x8
++#define IOMMU_PMU_CFG_FILTERS_OFFSET 0x4
++
++#define IOMMU_PMU_CAP_REGS_STEP 8
++
++#define iommu_cntrcap_pcc(p) ((p) & 0x1)
++#define iommu_cntrcap_cw(p) (((p) >> 8) & 0xff)
++#define iommu_cntrcap_ios(p) (((p) >> 16) & 0x1)
++#define iommu_cntrcap_egcnt(p) (((p) >> 28) & 0xf)
++
++#define iommu_event_select(p) ((p) & 0xfffffff)
++#define iommu_event_group(p) (((p) >> 28) & 0xf)
++
++#ifdef CONFIG_INTEL_IOMMU_PERF_EVENTS
++int alloc_iommu_pmu(struct intel_iommu *iommu);
++void free_iommu_pmu(struct intel_iommu *iommu);
++#else
++static inline int
++alloc_iommu_pmu(struct intel_iommu *iommu)
++{
++ return 0;
++}
++
++static inline void
++free_iommu_pmu(struct intel_iommu *iommu)
++{
++}
++#endif /* CONFIG_INTEL_IOMMU_PERF_EVENTS */
+--
+2.43.0
+
--- /dev/null
+From 03e2e7d628c559fb03e3f093002013d278927d6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 14:23:50 +0000
+Subject: ipmr: fix incorrect parameter validation in the
+ ip_mroute_getsockopt() function
+
+From: Gavrilov Ilia <Ilia.Gavrilov@infotecs.ru>
+
+[ Upstream commit 5c3be3e0eb44b7f978bb6cbb20ad956adb93f736 ]
+
+The 'olr' variable can't be negative when assigned the result of
+'min_t' because all 'min_t' parameters are cast to unsigned int,
+and then the minimum one is chosen.
+
+To fix the logic, check 'olr' as read from 'optlen',
+where the types of relevant variables are (signed) int.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Gavrilov Ilia <Ilia.Gavrilov@infotecs.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ipmr.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
+index d5421c38c2aae..3ed9ed2bffd29 100644
+--- a/net/ipv4/ipmr.c
++++ b/net/ipv4/ipmr.c
+@@ -1581,9 +1581,11 @@ int ip_mroute_getsockopt(struct sock *sk, int optname, sockptr_t optval,
+
+ if (copy_from_sockptr(&olr, optlen, sizeof(int)))
+ return -EFAULT;
+- olr = min_t(unsigned int, olr, sizeof(int));
+ if (olr < 0)
+ return -EINVAL;
++
++ olr = min_t(unsigned int, olr, sizeof(int));
++
+ if (copy_to_sockptr(optlen, &olr, sizeof(int)))
+ return -EFAULT;
+ if (copy_to_sockptr(optval, &val, olr))
+--
+2.43.0
+
--- /dev/null
+From 3a4e4dcc280919a4fc470f23eb1956961826c3bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 18:01:57 +0800
+Subject: ipv6: fib6_rules: flush route cache when rule is changed
+
+From: Shiming Cheng <shiming.cheng@mediatek.com>
+
+[ Upstream commit c4386ab4f6c600f75fdfd21143f89bac3e625d0d ]
+
+When rule policy is changed, ipv6 socket cache is not refreshed.
+The sock's skb still uses a outdated route cache and was sent to
+a wrong interface.
+
+To avoid this error we should update fib node's version when
+rule is changed. Then skb's route will be reroute checked as
+route cache version is already different with fib node version.
+The route cache is refreshed to match the latest rule.
+
+Fixes: 101367c2f8c4 ("[IPV6]: Policy Routing Rules")
+Signed-off-by: Shiming Cheng <shiming.cheng@mediatek.com>
+Signed-off-by: Lena Wang <lena.wang@mediatek.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/fib6_rules.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
+index 7c20038330104..be52b18e08a6b 100644
+--- a/net/ipv6/fib6_rules.c
++++ b/net/ipv6/fib6_rules.c
+@@ -449,6 +449,11 @@ static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule)
+ + nla_total_size(16); /* src */
+ }
+
++static void fib6_rule_flush_cache(struct fib_rules_ops *ops)
++{
++ rt_genid_bump_ipv6(ops->fro_net);
++}
++
+ static const struct fib_rules_ops __net_initconst fib6_rules_ops_template = {
+ .family = AF_INET6,
+ .rule_size = sizeof(struct fib6_rule),
+@@ -461,6 +466,7 @@ static const struct fib_rules_ops __net_initconst fib6_rules_ops_template = {
+ .compare = fib6_rule_compare,
+ .fill = fib6_rule_fill,
+ .nlmsg_payload = fib6_rule_nlmsg_payload,
++ .flush_cache = fib6_rule_flush_cache,
+ .nlgroup = RTNLGRP_IPV6_RULE,
+ .owner = THIS_MODULE,
+ .fro_net = &init_net,
+--
+2.43.0
+
--- /dev/null
+From 235b969fbc15aa9797b7de3636d2901469b24c76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Feb 2024 15:30:56 +0000
+Subject: ipv6: mcast: remove one synchronize_net() barrier in ipv6_mc_down()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 17ef8efc00b34918b966388b2af0993811895a8c ]
+
+As discussed in the past (commit 2d3916f31891 ("ipv6: fix skb drops
+in igmp6_event_query() and igmp6_event_report()")) I think the
+synchronize_net() call in ipv6_mc_down() is not needed.
+
+Under load, synchronize_net() can last between 200 usec and 5 ms.
+
+KASAN seems to agree as well.
+
+Fixes: f185de28d9ae ("mld: add new workqueues for process mld events")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Taehee Yoo <ap420073@gmail.com>
+Cc: Cong Wang <xiyou.wangcong@gmail.com>
+Cc: David Ahern <dsahern@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/mcast.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
+index 566f3b7b957e9..a777695389403 100644
+--- a/net/ipv6/mcast.c
++++ b/net/ipv6/mcast.c
+@@ -2722,7 +2722,6 @@ void ipv6_mc_down(struct inet6_dev *idev)
+ /* Should stop work after group drop. or we will
+ * start work again in mld_ifc_event()
+ */
+- synchronize_net();
+ mld_query_stop_work(idev);
+ mld_report_stop_work(idev);
+
+--
+2.43.0
+
--- /dev/null
+From 7c40a27c415d3f5ffdcfa6e9f0afb26bd25bac22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 14:23:50 +0000
+Subject: l2tp: fix incorrect parameter validation in the pppol2tp_getsockopt()
+ function
+
+From: Gavrilov Ilia <Ilia.Gavrilov@infotecs.ru>
+
+[ Upstream commit 955e9876ba4ee26eeaab1b13517f5b2c88e73d55 ]
+
+The 'len' variable can't be negative when assigned the result of
+'min_t' because all 'min_t' parameters are cast to unsigned int,
+and then the minimum one is chosen.
+
+To fix the logic, check 'len' as read from 'optlen',
+where the types of relevant variables are (signed) int.
+
+Fixes: 3557baabf280 ("[L2TP]: PPP over L2TP driver core")
+Reviewed-by: Tom Parkin <tparkin@katalix.com>
+Signed-off-by: Gavrilov Ilia <Ilia.Gavrilov@infotecs.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/l2tp/l2tp_ppp.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
+index f011af6601c9c..6146e4e67bbb5 100644
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -1356,11 +1356,11 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname,
+ if (get_user(len, optlen))
+ return -EFAULT;
+
+- len = min_t(unsigned int, len, sizeof(int));
+-
+ if (len < 0)
+ return -EINVAL;
+
++ len = min_t(unsigned int, len, sizeof(int));
++
+ err = -ENOTCONN;
+ if (!sk->sk_user_data)
+ goto end;
+--
+2.43.0
+
--- /dev/null
+From a8f1c74ca04f4f1d2040db984e2e22f94109b244 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Dec 2023 20:36:05 +0300
+Subject: leds: aw2013: Unlock mutex before destroying it
+
+From: George Stark <gnstark@salutedevices.com>
+
+[ Upstream commit 6969d0a2ba1adc9ba6a49b9805f24080896c255c ]
+
+In the probe() callback in case of error mutex is destroyed being locked
+which is not allowed so unlock the mutex before destroying.
+
+Fixes: 59ea3c9faf32 ("leds: add aw2013 driver")
+Signed-off-by: George Stark <gnstark@salutedevices.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20231214173614.2820929-2-gnstark@salutedevices.com
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/leds-aw2013.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/leds/leds-aw2013.c b/drivers/leds/leds-aw2013.c
+index 0b52fc9097c6e..3c05958578a1c 100644
+--- a/drivers/leds/leds-aw2013.c
++++ b/drivers/leds/leds-aw2013.c
+@@ -397,6 +397,7 @@ static int aw2013_probe(struct i2c_client *client)
+ regulator_disable(chip->vcc_regulator);
+
+ error:
++ mutex_unlock(&chip->mutex);
+ mutex_destroy(&chip->mutex);
+ return ret;
+ }
+--
+2.43.0
+
--- /dev/null
+From ed372649ea7d250a8594736a59b345ec955a7caf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Feb 2024 20:11:30 +0100
+Subject: leds: sgm3140: Add missing timer cleanup and flash gpio control
+
+From: Ondrej Jirman <megi@xff.cz>
+
+[ Upstream commit 205c29887a333ee4b37596e6533373e38cb23947 ]
+
+Enabling strobe and then setting brightness to 0 causes the driver to enter
+invalid state after strobe end timer fires. We should cancel strobe mode
+resources when changing brightness (aka torch mode).
+
+Fixes: cef8ec8cbd21 ("leds: add sgm3140 driver")
+Signed-off-by: Ondrej Jirman <megi@xff.cz>
+Link: https://lore.kernel.org/r/20240217191133.1757553-1-megi@xff.cz
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/flash/leds-sgm3140.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/leds/flash/leds-sgm3140.c b/drivers/leds/flash/leds-sgm3140.c
+index d3a30ad94ac46..dd5d327c52a10 100644
+--- a/drivers/leds/flash/leds-sgm3140.c
++++ b/drivers/leds/flash/leds-sgm3140.c
+@@ -114,8 +114,11 @@ static int sgm3140_brightness_set(struct led_classdev *led_cdev,
+ "failed to enable regulator: %d\n", ret);
+ return ret;
+ }
++ gpiod_set_value_cansleep(priv->flash_gpio, 0);
+ gpiod_set_value_cansleep(priv->enable_gpio, 1);
+ } else {
++ del_timer_sync(&priv->powerdown_timer);
++ gpiod_set_value_cansleep(priv->flash_gpio, 0);
+ gpiod_set_value_cansleep(priv->enable_gpio, 0);
+ ret = regulator_disable(priv->vin_regulator);
+ if (ret) {
+--
+2.43.0
+
--- /dev/null
+From 4e61707b97a325cdc8eb2fdc27521c5dd29e6b24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Feb 2024 17:27:15 +0800
+Subject: lib/cmdline: Fix an invalid format specifier in an assertion msg
+
+From: David Gow <davidgow@google.com>
+
+[ Upstream commit d2733a026fc7247ba42d7a8e1b737cf14bf1df21 ]
+
+The correct format specifier for p - n (both p and n are pointers) is
+%td, as the type should be ptrdiff_t.
+
+This was discovered by annotating KUnit assertion macros with gcc's
+printf specifier, but note that gcc incorrectly suggested a %d or %ld
+specifier (depending on the pointer size of the architecture being
+built).
+
+Fixes: 0ea09083116d ("lib/cmdline: Allow get_options() to take 0 to validate the input")
+Signed-off-by: David Gow <davidgow@google.com>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Daniel Latypov <dlatypov@google.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/cmdline_kunit.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/cmdline_kunit.c b/lib/cmdline_kunit.c
+index d4572dbc91453..705b82736be08 100644
+--- a/lib/cmdline_kunit.c
++++ b/lib/cmdline_kunit.c
+@@ -124,7 +124,7 @@ static void cmdline_do_one_range_test(struct kunit *test, const char *in,
+ n, e[0], r[0]);
+
+ p = memchr_inv(&r[1], 0, sizeof(r) - sizeof(r[0]));
+- KUNIT_EXPECT_PTR_EQ_MSG(test, p, NULL, "in test %u at %u out of bound", n, p - r);
++ KUNIT_EXPECT_PTR_EQ_MSG(test, p, NULL, "in test %u at %td out of bound", n, p - r);
+ }
+
+ static void cmdline_test_range(struct kunit *test)
+--
+2.43.0
+
--- /dev/null
+From 2afe9ed0d621e1193b5925aeaaa92b18cec5db93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Feb 2024 17:27:16 +0800
+Subject: lib: memcpy_kunit: Fix an invalid format specifier in an assertion
+ msg
+
+From: David Gow <davidgow@google.com>
+
+[ Upstream commit 0a549ed22c3c7cc6da5c5f5918efd019944489a5 ]
+
+The 'i' passed as an assertion message is a size_t, so should use '%zu',
+not '%d'.
+
+This was found by annotating the _MSG() variants of KUnit's assertions
+to let gcc validate the format strings.
+
+Fixes: bb95ebbe89a7 ("lib: Introduce CONFIG_MEMCPY_KUNIT_TEST")
+Signed-off-by: David Gow <davidgow@google.com>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Justin Stitt <justinstitt@google.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/memcpy_kunit.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/lib/memcpy_kunit.c b/lib/memcpy_kunit.c
+index 2b5cc70ac53fc..dbedd99aa6163 100644
+--- a/lib/memcpy_kunit.c
++++ b/lib/memcpy_kunit.c
+@@ -32,7 +32,7 @@ struct some_bytes {
+ BUILD_BUG_ON(sizeof(instance.data) != 32); \
+ for (size_t i = 0; i < sizeof(instance.data); i++) { \
+ KUNIT_ASSERT_EQ_MSG(test, instance.data[i], v, \
+- "line %d: '%s' not initialized to 0x%02x @ %d (saw 0x%02x)\n", \
++ "line %d: '%s' not initialized to 0x%02x @ %zu (saw 0x%02x)\n", \
+ __LINE__, #instance, v, i, instance.data[i]); \
+ } \
+ } while (0)
+@@ -41,7 +41,7 @@ struct some_bytes {
+ BUILD_BUG_ON(sizeof(one) != sizeof(two)); \
+ for (size_t i = 0; i < sizeof(one); i++) { \
+ KUNIT_EXPECT_EQ_MSG(test, one.data[i], two.data[i], \
+- "line %d: %s.data[%d] (0x%02x) != %s.data[%d] (0x%02x)\n", \
++ "line %d: %s.data[%zu] (0x%02x) != %s.data[%zu] (0x%02x)\n", \
+ __LINE__, #one, i, one.data[i], #two, i, two.data[i]); \
+ } \
+ kunit_info(test, "ok: " TEST_OP "() " name "\n"); \
+--
+2.43.0
+
--- /dev/null
+From a5348aea6a873924343a485cb9890e782c476086 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Feb 2024 09:20:24 -0800
+Subject: libbpf: Add missing LIBBPF_API annotation to libbpf_set_memlock_rlim
+ API
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit 93ee1eb85e28d1e35bb059c1f5965d65d5fc83c2 ]
+
+LIBBPF_API annotation seems missing on libbpf_set_memlock_rlim API, so
+add it to make this API callable from libbpf's shared library version.
+
+Fixes: e542f2c4cd16 ("libbpf: Auto-bump RLIMIT_MEMLOCK if kernel needs it for BPF")
+Fixes: ab9a5a05dc48 ("libbpf: fix up few libbpf.map problems")
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Eduard Zingerman <eddyz87@gmail.com>
+Link: https://lore.kernel.org/bpf/20240201172027.604869-3-andrii@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/bpf.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
+index fddc05c667b5d..874fe362375de 100644
+--- a/tools/lib/bpf/bpf.h
++++ b/tools/lib/bpf/bpf.h
+@@ -35,7 +35,7 @@
+ extern "C" {
+ #endif
+
+-int libbpf_set_memlock_rlim(size_t memlock_bytes);
++LIBBPF_API int libbpf_set_memlock_rlim(size_t memlock_bytes);
+
+ struct bpf_map_create_opts {
+ size_t sz; /* size of this struct for forward/backward compatibility */
+--
+2.43.0
+
--- /dev/null
+From 6785caee4ae706512700fb0e2c5ed269b0679d55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 16:06:18 +0300
+Subject: libbpf: Apply map_set_def_max_entries() for inner_maps on creation
+
+From: Andrey Grafin <conquistador@yandex-team.ru>
+
+[ Upstream commit f04deb90e516e8e48bf8693397529bc942a9e80b ]
+
+This patch allows to auto create BPF_MAP_TYPE_ARRAY_OF_MAPS and
+BPF_MAP_TYPE_HASH_OF_MAPS with values of BPF_MAP_TYPE_PERF_EVENT_ARRAY
+by bpf_object__load().
+
+Previous behaviour created a zero filled btf_map_def for inner maps and
+tried to use it for a map creation but the linux kernel forbids to create
+a BPF_MAP_TYPE_PERF_EVENT_ARRAY map with max_entries=0.
+
+Fixes: 646f02ffdd49 ("libbpf: Add BTF-defined map-in-map support")
+Signed-off-by: Andrey Grafin <conquistador@yandex-team.ru>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Yonghong Song <yonghong.song@linux.dev>
+Acked-by: Hou Tao <houtao1@huawei.com>
+Link: https://lore.kernel.org/bpf/20240117130619.9403-1-conquistador@yandex-team.ru
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/libbpf.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index e2014b1250ea2..c71d4d0f5c6f3 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -70,6 +70,7 @@
+
+ static struct bpf_map *bpf_object__add_map(struct bpf_object *obj);
+ static bool prog_is_subprog(const struct bpf_object *obj, const struct bpf_program *prog);
++static int map_set_def_max_entries(struct bpf_map *map);
+
+ static const char * const attach_type_name[] = {
+ [BPF_CGROUP_INET_INGRESS] = "cgroup_inet_ingress",
+@@ -4992,6 +4993,9 @@ static int bpf_object__create_map(struct bpf_object *obj, struct bpf_map *map, b
+
+ if (bpf_map_type__is_map_in_map(def->type)) {
+ if (map->inner_map) {
++ err = map_set_def_max_entries(map->inner_map);
++ if (err)
++ return err;
+ err = bpf_object__create_map(obj, map->inner_map, true);
+ if (err) {
+ pr_warn("map '%s': failed to create inner map: %d\n",
+--
+2.43.0
+
--- /dev/null
+From 3f5d41e45e7ec16b21a154393772fbe596fadcbc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Jan 2024 14:09:44 -0800
+Subject: libbpf: Fix faccessat() usage on Android
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit ad57654053805bf9a62602aaec74cc78edb6f235 ]
+
+Android implementation of libc errors out with -EINVAL in faccessat() if
+passed AT_EACCESS ([0]), this leads to ridiculous issue with libbpf
+refusing to load /sys/kernel/btf/vmlinux on Androids ([1]). Fix by
+detecting Android and redefining AT_EACCESS to 0, it's equivalent on
+Android.
+
+ [0] https://android.googlesource.com/platform/bionic/+/refs/heads/android13-release/libc/bionic/faccessat.cpp#50
+ [1] https://github.com/libbpf/libbpf-bootstrap/issues/250#issuecomment-1911324250
+
+Fixes: 6a4ab8869d0b ("libbpf: Fix the case of running as non-root with capabilities")
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Jiri Olsa <jolsa@kernel.org>
+Link: https://lore.kernel.org/bpf/20240126220944.2497665-1-andrii@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/libbpf_internal.h | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h
+index 377642ff51fce..8669f6e0f6e2f 100644
+--- a/tools/lib/bpf/libbpf_internal.h
++++ b/tools/lib/bpf/libbpf_internal.h
+@@ -17,6 +17,20 @@
+ #include <unistd.h>
+ #include "relo_core.h"
+
++/* Android's libc doesn't support AT_EACCESS in faccessat() implementation
++ * ([0]), and just returns -EINVAL even if file exists and is accessible.
++ * See [1] for issues caused by this.
++ *
++ * So just redefine it to 0 on Android.
++ *
++ * [0] https://android.googlesource.com/platform/bionic/+/refs/heads/android13-release/libc/bionic/faccessat.cpp#50
++ * [1] https://github.com/libbpf/libbpf-bootstrap/issues/250#issuecomment-1911324250
++ */
++#ifdef __ANDROID__
++#undef AT_EACCESS
++#define AT_EACCESS 0
++#endif
++
+ /* make sure libbpf doesn't use kernel-only integer typedefs */
+ #pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
+
+--
+2.43.0
+
--- /dev/null
+From 3c4aafc79c8ce75a1313bf41c813caf5071374b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Feb 2024 11:14:40 +0800
+Subject: md: Don't clear MD_CLOSING when the raid is about to stop
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit 9674f54e41fffaf06f6a60202e1fa4cc13de3cf5 ]
+
+The raid should not be opened anymore when it is about to be stopped.
+However, other processes can open it again if the flag MD_CLOSING is
+cleared before exiting. From now on, this flag will not be cleared when
+the raid will be stopped.
+
+Fixes: 065e519e71b2 ("md: MD_CLOSING needs to be cleared after called md_set_readonly or do_md_stop")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20240226031444.3606764-6-linan666@huaweicloud.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/md.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 1c87f3e708094..788acc81e7a84 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -6243,7 +6243,15 @@ static void md_clean(struct mddev *mddev)
+ mddev->persistent = 0;
+ mddev->level = LEVEL_NONE;
+ mddev->clevel[0] = 0;
+- mddev->flags = 0;
++ /*
++ * Don't clear MD_CLOSING, or mddev can be opened again.
++ * 'hold_active != 0' means mddev is still in the creation
++ * process and will be used later.
++ */
++ if (mddev->hold_active)
++ mddev->flags = 0;
++ else
++ mddev->flags &= BIT_ULL_MASK(MD_CLOSING);
+ mddev->sb_flags = 0;
+ mddev->ro = MD_RDWR;
+ mddev->metadata_type[0] = 0;
+@@ -7571,7 +7579,6 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
+ int err = 0;
+ void __user *argp = (void __user *)arg;
+ struct mddev *mddev = NULL;
+- bool did_set_md_closing = false;
+
+ if (!md_ioctl_valid(cmd))
+ return -ENOTTY;
+@@ -7658,7 +7665,6 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
+ err = -EBUSY;
+ goto out;
+ }
+- did_set_md_closing = true;
+ mutex_unlock(&mddev->open_mutex);
+ sync_blockdev(bdev);
+ }
+@@ -7821,7 +7827,7 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
+ mddev->hold_active = 0;
+ mddev_unlock(mddev);
+ out:
+- if(did_set_md_closing)
++ if (cmd == STOP_ARRAY_RO || (err && cmd == STOP_ARRAY))
+ clear_bit(MD_CLOSING, &mddev->flags);
+ return err;
+ }
+--
+2.43.0
+
--- /dev/null
+From 33d83029db89845b145f23083c83e46d972d0cee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Oct 2022 19:45:50 +0200
+Subject: media: cedrus: h265: Associate mv col buffers with buffer
+
+From: Jernej Skrabec <jernej.skrabec@gmail.com>
+
+[ Upstream commit 0ee952c2f484ee0059f7ce4951aaa3cb0eda96dd ]
+
+Currently mv col aux buffers are allocated as a pool. This is not
+optimal because pool size equals number of buffers before stream is
+started. Buffers can easily be allocated afterwards. In such cases,
+invalid pointer is assigned to the decoding frame and Cedrus might
+overwrite memory location which is allocated to different task.
+
+Solve this issue with allocating mv col buffer once capture buffer is
+actually used.
+
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Stable-dep-of: 3a11887f7f11 ("media: cedrus: h265: Fix configuring bitstream size")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/sunxi/cedrus/cedrus.h | 9 +--
+ .../staging/media/sunxi/cedrus/cedrus_h265.c | 63 ++++++++++---------
+ 2 files changed, 38 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
+index 93a2196006f73..cb99610f3e128 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
++++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
+@@ -109,6 +109,11 @@ struct cedrus_buffer {
+ unsigned int position;
+ enum cedrus_h264_pic_type pic_type;
+ } h264;
++ struct {
++ void *mv_col_buf;
++ dma_addr_t mv_col_buf_dma;
++ ssize_t mv_col_buf_size;
++ } h265;
+ } codec;
+ };
+
+@@ -142,10 +147,6 @@ struct cedrus_ctx {
+ ssize_t intra_pred_buf_size;
+ } h264;
+ struct {
+- void *mv_col_buf;
+- dma_addr_t mv_col_buf_addr;
+- ssize_t mv_col_buf_size;
+- ssize_t mv_col_buf_unit_size;
+ void *neighbor_info_buf;
+ dma_addr_t neighbor_info_buf_addr;
+ void *entry_points_buf;
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+index 625f77a8c5bde..7a438cd22c341 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+@@ -90,12 +90,13 @@ static void cedrus_h265_sram_write_data(struct cedrus_dev *dev, void *data,
+ }
+
+ static inline dma_addr_t
+-cedrus_h265_frame_info_mv_col_buf_addr(struct cedrus_ctx *ctx,
+- unsigned int index, unsigned int field)
++cedrus_h265_frame_info_mv_col_buf_addr(struct vb2_buffer *buf,
++ unsigned int field)
+ {
+- return ctx->codec.h265.mv_col_buf_addr + index *
+- ctx->codec.h265.mv_col_buf_unit_size +
+- field * ctx->codec.h265.mv_col_buf_unit_size / 2;
++ struct cedrus_buffer *cedrus_buf = vb2_to_cedrus_buffer(buf);
++
++ return cedrus_buf->codec.h265.mv_col_buf_dma +
++ field * cedrus_buf->codec.h265.mv_col_buf_size / 2;
+ }
+
+ static void cedrus_h265_frame_info_write_single(struct cedrus_ctx *ctx,
+@@ -108,9 +109,8 @@ static void cedrus_h265_frame_info_write_single(struct cedrus_ctx *ctx,
+ dma_addr_t dst_luma_addr = cedrus_dst_buf_addr(ctx, buf, 0);
+ dma_addr_t dst_chroma_addr = cedrus_dst_buf_addr(ctx, buf, 1);
+ dma_addr_t mv_col_buf_addr[2] = {
+- cedrus_h265_frame_info_mv_col_buf_addr(ctx, buf->index, 0),
+- cedrus_h265_frame_info_mv_col_buf_addr(ctx, buf->index,
+- field_pic ? 1 : 0)
++ cedrus_h265_frame_info_mv_col_buf_addr(buf, 0),
++ cedrus_h265_frame_info_mv_col_buf_addr(buf, field_pic ? 1 : 0)
+ };
+ u32 offset = VE_DEC_H265_SRAM_OFFSET_FRAME_INFO +
+ VE_DEC_H265_SRAM_OFFSET_FRAME_INFO_UNIT * index;
+@@ -412,6 +412,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
+ unsigned int width_in_ctb_luma, ctb_size_luma;
+ unsigned int log2_max_luma_coding_block_size;
+ unsigned int ctb_addr_x, ctb_addr_y;
++ struct cedrus_buffer *cedrus_buf;
+ dma_addr_t src_buf_addr;
+ dma_addr_t src_buf_end_addr;
+ u32 chroma_log2_weight_denom;
+@@ -428,6 +429,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
+ decode_params = run->h265.decode_params;
+ pred_weight_table = &slice_params->pred_weight_table;
+ num_entry_point_offsets = slice_params->num_entry_point_offsets;
++ cedrus_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf);
+
+ /*
+ * If entry points offsets are present, we should get them
+@@ -445,31 +447,25 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
+ DIV_ROUND_UP(sps->pic_width_in_luma_samples, ctb_size_luma);
+
+ /* MV column buffer size and allocation. */
+- if (!ctx->codec.h265.mv_col_buf_size) {
+- unsigned int num_buffers =
+- run->dst->vb2_buf.vb2_queue->num_buffers;
+-
++ if (!cedrus_buf->codec.h265.mv_col_buf_size) {
+ /*
+ * Each CTB requires a MV col buffer with a specific unit size.
+ * Since the address is given with missing lsb bits, 1 KiB is
+ * added to each buffer to ensure proper alignment.
+ */
+- ctx->codec.h265.mv_col_buf_unit_size =
++ cedrus_buf->codec.h265.mv_col_buf_size =
+ DIV_ROUND_UP(ctx->src_fmt.width, ctb_size_luma) *
+ DIV_ROUND_UP(ctx->src_fmt.height, ctb_size_luma) *
+ CEDRUS_H265_MV_COL_BUF_UNIT_CTB_SIZE + SZ_1K;
+
+- ctx->codec.h265.mv_col_buf_size = num_buffers *
+- ctx->codec.h265.mv_col_buf_unit_size;
+-
+ /* Buffer is never accessed by CPU, so we can skip kernel mapping. */
+- ctx->codec.h265.mv_col_buf =
++ cedrus_buf->codec.h265.mv_col_buf =
+ dma_alloc_attrs(dev->dev,
+- ctx->codec.h265.mv_col_buf_size,
+- &ctx->codec.h265.mv_col_buf_addr,
++ cedrus_buf->codec.h265.mv_col_buf_size,
++ &cedrus_buf->codec.h265.mv_col_buf_dma,
+ GFP_KERNEL, DMA_ATTR_NO_KERNEL_MAPPING);
+- if (!ctx->codec.h265.mv_col_buf) {
+- ctx->codec.h265.mv_col_buf_size = 0;
++ if (!cedrus_buf->codec.h265.mv_col_buf) {
++ cedrus_buf->codec.h265.mv_col_buf_size = 0;
+ return -ENOMEM;
+ }
+ }
+@@ -816,9 +812,6 @@ static int cedrus_h265_start(struct cedrus_ctx *ctx)
+ {
+ struct cedrus_dev *dev = ctx->dev;
+
+- /* The buffer size is calculated at setup time. */
+- ctx->codec.h265.mv_col_buf_size = 0;
+-
+ /* Buffer is never accessed by CPU, so we can skip kernel mapping. */
+ ctx->codec.h265.neighbor_info_buf =
+ dma_alloc_attrs(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE,
+@@ -845,14 +838,24 @@ static int cedrus_h265_start(struct cedrus_ctx *ctx)
+ static void cedrus_h265_stop(struct cedrus_ctx *ctx)
+ {
+ struct cedrus_dev *dev = ctx->dev;
++ struct cedrus_buffer *buf;
++ struct vb2_queue *vq;
++ unsigned int i;
+
+- if (ctx->codec.h265.mv_col_buf_size > 0) {
+- dma_free_attrs(dev->dev, ctx->codec.h265.mv_col_buf_size,
+- ctx->codec.h265.mv_col_buf,
+- ctx->codec.h265.mv_col_buf_addr,
+- DMA_ATTR_NO_KERNEL_MAPPING);
++ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
++
++ for (i = 0; i < vq->num_buffers; i++) {
++ buf = vb2_to_cedrus_buffer(vb2_get_buffer(vq, i));
+
+- ctx->codec.h265.mv_col_buf_size = 0;
++ if (buf->codec.h265.mv_col_buf_size > 0) {
++ dma_free_attrs(dev->dev,
++ buf->codec.h265.mv_col_buf_size,
++ buf->codec.h265.mv_col_buf,
++ buf->codec.h265.mv_col_buf_dma,
++ DMA_ATTR_NO_KERNEL_MAPPING);
++
++ buf->codec.h265.mv_col_buf_size = 0;
++ }
+ }
+
+ dma_free_attrs(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE,
+--
+2.43.0
+
--- /dev/null
+From d2a7a73f756adf1ea23f8d1bd78f5287ad54cd11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 Dec 2023 14:09:25 +0100
+Subject: media: cedrus: h265: Fix configuring bitstream size
+
+From: Jernej Skrabec <jernej.skrabec@gmail.com>
+
+[ Upstream commit 3a11887f7f11a6bb1f05e7f67b3ea20dadfec443 ]
+
+bit_size field holds size of slice, not slice + header. Because of HW
+quirks, driver can't program in just slice, but also preceding header.
+But that means that currently used bit_size is wrong (too small).
+Instead, just use size of whole buffer. There is no harm in doing this.
+
+Fixes: 86caab29da78 ("media: cedrus: Add HEVC/H.265 decoding support")
+Suggested-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+index 7a438cd22c341..9f13c942a806b 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+@@ -414,11 +414,11 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
+ unsigned int ctb_addr_x, ctb_addr_y;
+ struct cedrus_buffer *cedrus_buf;
+ dma_addr_t src_buf_addr;
+- dma_addr_t src_buf_end_addr;
+ u32 chroma_log2_weight_denom;
+ u32 num_entry_point_offsets;
+ u32 output_pic_list_index;
+ u32 pic_order_cnt[2];
++ size_t slice_bytes;
+ u8 padding;
+ int count;
+ u32 reg;
+@@ -430,6 +430,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
+ pred_weight_table = &slice_params->pred_weight_table;
+ num_entry_point_offsets = slice_params->num_entry_point_offsets;
+ cedrus_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf);
++ slice_bytes = vb2_get_plane_payload(&run->src->vb2_buf, 0);
+
+ /*
+ * If entry points offsets are present, we should get them
+@@ -477,7 +478,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
+
+ cedrus_write(dev, VE_DEC_H265_BITS_OFFSET, 0);
+
+- reg = slice_params->bit_size;
++ reg = slice_bytes * 8;
+ cedrus_write(dev, VE_DEC_H265_BITS_LEN, reg);
+
+ /* Source beginning and end addresses. */
+@@ -491,10 +492,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
+
+ cedrus_write(dev, VE_DEC_H265_BITS_ADDR, reg);
+
+- src_buf_end_addr = src_buf_addr +
+- DIV_ROUND_UP(slice_params->bit_size, 8);
+-
+- reg = VE_DEC_H265_BITS_END_ADDR_BASE(src_buf_end_addr);
++ reg = VE_DEC_H265_BITS_END_ADDR_BASE(src_buf_addr + slice_bytes);
+ cedrus_write(dev, VE_DEC_H265_BITS_END_ADDR, reg);
+
+ /* Coding tree block address */
+--
+2.43.0
+
--- /dev/null
+From edb743e4900f8813e5e16cb18914c26be560ac20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Feb 2024 17:31:44 +0100
+Subject: media: dvb-frontends: avoid stack overflow warnings with clang
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 7a4cf27d1f0538f779bf31b8c99eda394e277119 ]
+
+A previous patch worked around a KASAN issue in stv0367, now a similar
+problem showed up with clang:
+
+drivers/media/dvb-frontends/stv0367.c:1222:12: error: stack frame size (3624) exceeds limit (2048) in 'stv0367ter_set_frontend' [-Werror,-Wframe-larger-than]
+ 1214 | static int stv0367ter_set_frontend(struct dvb_frontend *fe)
+
+Rework the stv0367_writereg() function to be simpler and mark both
+register access functions as noinline_for_stack so the temporary
+i2c_msg structures do not get duplicated on the stack when KASAN_STACK
+is enabled.
+
+Fixes: 3cd890dbe2a4 ("media: dvb-frontends: fix i2c access helpers for KASAN")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Justin Stitt <justinstitt@google.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/dvb-frontends/stv0367.c | 34 +++++++--------------------
+ 1 file changed, 8 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c
+index 04556b77c16c9..0977564a4a1a4 100644
+--- a/drivers/media/dvb-frontends/stv0367.c
++++ b/drivers/media/dvb-frontends/stv0367.c
+@@ -118,50 +118,32 @@ static const s32 stv0367cab_RF_LookUp2[RF_LOOKUP_TABLE2_SIZE][RF_LOOKUP_TABLE2_S
+ }
+ };
+
+-static
+-int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len)
++static noinline_for_stack
++int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
+ {
+- u8 buf[MAX_XFER_SIZE];
++ u8 buf[3] = { MSB(reg), LSB(reg), data };
+ struct i2c_msg msg = {
+ .addr = state->config->demod_address,
+ .flags = 0,
+ .buf = buf,
+- .len = len + 2
++ .len = 3,
+ };
+ int ret;
+
+- if (2 + len > sizeof(buf)) {
+- printk(KERN_WARNING
+- "%s: i2c wr reg=%04x: len=%d is too big!\n",
+- KBUILD_MODNAME, reg, len);
+- return -EINVAL;
+- }
+-
+-
+- buf[0] = MSB(reg);
+- buf[1] = LSB(reg);
+- memcpy(buf + 2, data, len);
+-
+ if (i2cdebug)
+ printk(KERN_DEBUG "%s: [%02x] %02x: %02x\n", __func__,
+- state->config->demod_address, reg, buf[2]);
++ state->config->demod_address, reg, data);
+
+ ret = i2c_transfer(state->i2c, &msg, 1);
+ if (ret != 1)
+ printk(KERN_ERR "%s: i2c write error! ([%02x] %02x: %02x)\n",
+- __func__, state->config->demod_address, reg, buf[2]);
++ __func__, state->config->demod_address, reg, data);
+
+ return (ret != 1) ? -EREMOTEIO : 0;
+ }
+
+-static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
+-{
+- u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+-
+- return stv0367_writeregs(state, reg, &tmp, 1);
+-}
+-
+-static u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
++static noinline_for_stack
++u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
+ {
+ u8 b0[] = { 0, 0 };
+ u8 b1[] = { 0 };
+--
+2.43.0
+
--- /dev/null
+From 5f86067b3eb5c4dd54f7cb8d44c968ba34f4b615 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 3 Feb 2024 14:40:43 +0100
+Subject: media: edia: dvbdev: fix a use-after-free
+
+From: Zhipeng Lu <alexious@zju.edu.cn>
+
+[ Upstream commit 8c64f4cdf4e6cc5682c52523713af8c39c94e6d5 ]
+
+In dvb_register_device, *pdvbdev is set equal to dvbdev, which is freed
+in several error-handling paths. However, *pdvbdev is not set to NULL
+after dvbdev's deallocation, causing use-after-frees in many places,
+for example, in the following call chain:
+
+budget_register
+ |-> dvb_dmxdev_init
+ |-> dvb_register_device
+ |-> dvb_dmxdev_release
+ |-> dvb_unregister_device
+ |-> dvb_remove_device
+ |-> dvb_device_put
+ |-> kref_put
+
+When calling dvb_unregister_device, dmxdev->dvbdev (i.e. *pdvbdev in
+dvb_register_device) could point to memory that had been freed in
+dvb_register_device. Thereafter, this pointer is transferred to
+kref_put and triggering a use-after-free.
+
+Link: https://lore.kernel.org/linux-media/20240203134046.3120099-1-alexious@zju.edu.cn
+Fixes: b61901024776 ("V4L/DVB (5244): Dvbdev: fix illegal re-usage of fileoperations struct")
+Signed-off-by: Zhipeng Lu <alexious@zju.edu.cn>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/dvb-core/dvbdev.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
+index d352e028491aa..aefee2277254d 100644
+--- a/drivers/media/dvb-core/dvbdev.c
++++ b/drivers/media/dvb-core/dvbdev.c
+@@ -494,6 +494,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
+ dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL);
+ if (!dvbdevfops) {
+ kfree(dvbdev);
++ *pdvbdev = NULL;
+ mutex_unlock(&dvbdev_register_lock);
+ return -ENOMEM;
+ }
+@@ -502,6 +503,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
+ if (!new_node) {
+ kfree(dvbdevfops);
+ kfree(dvbdev);
++ *pdvbdev = NULL;
+ mutex_unlock(&dvbdev_register_lock);
+ return -ENOMEM;
+ }
+@@ -535,6 +537,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
+ }
+ list_del (&dvbdev->list_head);
+ kfree(dvbdev);
++ *pdvbdev = NULL;
+ up_write(&minor_rwsem);
+ mutex_unlock(&dvbdev_register_lock);
+ return -EINVAL;
+@@ -557,6 +560,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
+ dvb_media_device_free(dvbdev);
+ list_del (&dvbdev->list_head);
+ kfree(dvbdev);
++ *pdvbdev = NULL;
+ mutex_unlock(&dvbdev_register_lock);
+ return ret;
+ }
+@@ -575,6 +579,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
+ dvb_media_device_free(dvbdev);
+ list_del (&dvbdev->list_head);
+ kfree(dvbdev);
++ *pdvbdev = NULL;
+ mutex_unlock(&dvbdev_register_lock);
+ return PTR_ERR(clsdev);
+ }
+--
+2.43.0
+
--- /dev/null
+From bd74bc91b5d8480dac245e804b072bb3ba432ec9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jan 2024 05:42:26 -0800
+Subject: media: em28xx: annotate unchecked call to media_device_register()
+
+From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+
+[ Upstream commit fd61d77a3d28444b2635f0c8b5a2ecd6a4d94026 ]
+
+Static analyzers generate alerts for an unchecked call to
+`media_device_register()`. However, in this case, the device will work
+reliably without the media controller API.
+
+Add a comment above the call to prevent future unnecessary changes.
+
+Suggested-by: Mauro Carvalho Chehab <mchehab@kernel.org>
+Fixes: 37ecc7b1278f ("[media] em28xx: add media controller support")
+Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/em28xx/em28xx-cards.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
+index 4d037c92af7c5..bae76023cf71d 100644
+--- a/drivers/media/usb/em28xx/em28xx-cards.c
++++ b/drivers/media/usb/em28xx/em28xx-cards.c
+@@ -4094,6 +4094,10 @@ static int em28xx_usb_probe(struct usb_interface *intf,
+ * topology will likely change after the load of the em28xx subdrivers.
+ */
+ #ifdef CONFIG_MEDIA_CONTROLLER
++ /*
++ * No need to check the return value, the device will still be
++ * usable without media controller API.
++ */
+ retval = media_device_register(dev->media_dev);
+ #endif
+
+--
+2.43.0
+
--- /dev/null
+From 6414c030f9cae3423d4cc5f826f1189cda0e8951 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Feb 2024 07:07:05 -0800
+Subject: media: go7007: add check of return value of go7007_read_addr()
+
+From: Daniil Dulov <d.dulov@aladdin.ru>
+
+[ Upstream commit 0b70530ee740861f4776ff724fcc25023df1799a ]
+
+If go7007_read_addr() returns error channel is not assigned a value.
+In this case go to allocfail.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 866b8695d67e ("Staging: add the go7007 video driver")
+Signed-off-by: Daniil Dulov <d.dulov@aladdin.ru>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/go7007/go7007-usb.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/usb/go7007/go7007-usb.c b/drivers/media/usb/go7007/go7007-usb.c
+index eeb85981e02b6..762c13e49bfa5 100644
+--- a/drivers/media/usb/go7007/go7007-usb.c
++++ b/drivers/media/usb/go7007/go7007-usb.c
+@@ -1201,7 +1201,9 @@ static int go7007_usb_probe(struct usb_interface *intf,
+ u16 channel;
+
+ /* read channel number from GPIO[1:0] */
+- go7007_read_addr(go, 0x3c81, &channel);
++ if (go7007_read_addr(go, 0x3c81, &channel))
++ goto allocfail;
++
+ channel &= 0x3;
+ go->board_id = GO7007_BOARDID_ADLINK_MPG24;
+ usb->board = board = &board_adlink_mpg24;
+--
+2.43.0
+
--- /dev/null
+From ae75600652109591e04b6ffc46d738a0fa488b4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Feb 2024 12:37:13 +0800
+Subject: media: go7007: fix a memleak in go7007_load_encoder
+
+From: Zhipeng Lu <alexious@zju.edu.cn>
+
+[ Upstream commit b9b683844b01d171a72b9c0419a2d760d946ee12 ]
+
+In go7007_load_encoder, bounce(i.e. go->boot_fw), is allocated without
+a deallocation thereafter. After the following call chain:
+
+saa7134_go7007_init
+ |-> go7007_boot_encoder
+ |-> go7007_load_encoder
+ |-> kfree(go)
+
+go is freed and thus bounce is leaked.
+
+Fixes: 95ef39403f89 ("[media] go7007: remember boot firmware")
+Signed-off-by: Zhipeng Lu <alexious@zju.edu.cn>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/go7007/go7007-driver.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/usb/go7007/go7007-driver.c b/drivers/media/usb/go7007/go7007-driver.c
+index 0c24e29843048..eb03f98b2ef11 100644
+--- a/drivers/media/usb/go7007/go7007-driver.c
++++ b/drivers/media/usb/go7007/go7007-driver.c
+@@ -80,7 +80,7 @@ static int go7007_load_encoder(struct go7007 *go)
+ const struct firmware *fw_entry;
+ char fw_name[] = "go7007/go7007fw.bin";
+ void *bounce;
+- int fw_len, rv = 0;
++ int fw_len;
+ u16 intr_val, intr_data;
+
+ if (go->boot_fw == NULL) {
+@@ -109,9 +109,11 @@ static int go7007_load_encoder(struct go7007 *go)
+ go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
+ (intr_val & ~0x1) != 0x5a5a) {
+ v4l2_err(go, "error transferring firmware\n");
+- rv = -1;
++ kfree(go->boot_fw);
++ go->boot_fw = NULL;
++ return -1;
+ }
+- return rv;
++ return 0;
+ }
+
+ MODULE_FIRMWARE("go7007/go7007fw.bin");
+--
+2.43.0
+
--- /dev/null
+From e75152822352605019e0384768d89fdb7c48d2f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jan 2024 13:00:33 +0100
+Subject: media: imx: csc/scaler: fix v4l2_ctrl_handler memory leak
+
+From: Lucas Stach <l.stach@pengutronix.de>
+
+[ Upstream commit 4797a3dd46f220e6d83daf54d70c5b33db6deb01 ]
+
+Free the memory allocated in v4l2_ctrl_handler_init on release.
+
+Fixes: a8ef0488cc59 ("media: imx: add csc/scaler mem2mem device")
+Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
+Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/imx/imx-media-csc-scaler.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/staging/media/imx/imx-media-csc-scaler.c b/drivers/staging/media/imx/imx-media-csc-scaler.c
+index 1fd39a2fca98a..95cca281e8a37 100644
+--- a/drivers/staging/media/imx/imx-media-csc-scaler.c
++++ b/drivers/staging/media/imx/imx-media-csc-scaler.c
+@@ -803,6 +803,7 @@ static int ipu_csc_scaler_release(struct file *file)
+
+ dev_dbg(priv->dev, "Releasing instance %p\n", ctx);
+
++ v4l2_ctrl_handler_free(&ctx->ctrl_hdlr);
+ v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+--
+2.43.0
+
--- /dev/null
+From ef3de25bd250fe4a71889ddde7a1109d82ec54e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 Feb 2024 13:10:22 +0100
+Subject: media: mediatek: vcodec: avoid -Wcast-function-type-strict warning
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit bfb1b99802ef16045402deb855c197591dc78886 ]
+
+The ipi handler here tries hard to maintain const-ness of its argument,
+but by doing that causes a warning about function type casts:
+
+drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c:38:32: error: cast from 'mtk_vcodec_ipi_handler' (aka 'void (*)(void *, unsigned int, void *)') to 'ipi_handler_t' (aka 'void (*)(const void *, unsigned int, void *)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+ 38 | ipi_handler_t handler_const = (ipi_handler_t)handler;
+ | ^~~~~~~~~~~~~~~~~~~~~~
+
+Remove the hack and just use a non-const argument.
+
+Fixes: bf1d556ad4e0 ("media: mtk-vcodec: abstract firmware interface")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c | 2 +-
+ .../media/platform/mediatek/vcodec/mtk_vcodec_fw_vpu.c | 10 +---------
+ drivers/media/platform/mediatek/vpu/mtk_vpu.c | 2 +-
+ drivers/media/platform/mediatek/vpu/mtk_vpu.h | 2 +-
+ 4 files changed, 4 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c b/drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c
+index b065ccd069140..378a1cba0144f 100644
+--- a/drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c
++++ b/drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c
+@@ -26,7 +26,7 @@ static void mtk_mdp_vpu_handle_init_ack(const struct mdp_ipi_comm_ack *msg)
+ vpu->inst_addr = msg->vpu_inst_addr;
+ }
+
+-static void mtk_mdp_vpu_ipi_handler(const void *data, unsigned int len,
++static void mtk_mdp_vpu_ipi_handler(void *data, unsigned int len,
+ void *priv)
+ {
+ const struct mdp_ipi_comm_ack *msg = data;
+diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_vpu.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_vpu.c
+index cfc7ebed8fb7a..1ec29f1b163a1 100644
+--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_vpu.c
++++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_fw_vpu.c
+@@ -29,15 +29,7 @@ static int mtk_vcodec_vpu_set_ipi_register(struct mtk_vcodec_fw *fw, int id,
+ mtk_vcodec_ipi_handler handler,
+ const char *name, void *priv)
+ {
+- /*
+- * The handler we receive takes a void * as its first argument. We
+- * cannot change this because it needs to be passed down to the rproc
+- * subsystem when SCP is used. VPU takes a const argument, which is
+- * more constrained, so the conversion below is safe.
+- */
+- ipi_handler_t handler_const = (ipi_handler_t)handler;
+-
+- return vpu_ipi_register(fw->pdev, id, handler_const, name, priv);
++ return vpu_ipi_register(fw->pdev, id, handler, name, priv);
+ }
+
+ static int mtk_vcodec_vpu_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf,
+diff --git a/drivers/media/platform/mediatek/vpu/mtk_vpu.c b/drivers/media/platform/mediatek/vpu/mtk_vpu.c
+index 6beab9e86a22a..44adf5cfc9bb2 100644
+--- a/drivers/media/platform/mediatek/vpu/mtk_vpu.c
++++ b/drivers/media/platform/mediatek/vpu/mtk_vpu.c
+@@ -635,7 +635,7 @@ int vpu_load_firmware(struct platform_device *pdev)
+ }
+ EXPORT_SYMBOL_GPL(vpu_load_firmware);
+
+-static void vpu_init_ipi_handler(const void *data, unsigned int len, void *priv)
++static void vpu_init_ipi_handler(void *data, unsigned int len, void *priv)
+ {
+ struct mtk_vpu *vpu = priv;
+ const struct vpu_run *run = data;
+diff --git a/drivers/media/platform/mediatek/vpu/mtk_vpu.h b/drivers/media/platform/mediatek/vpu/mtk_vpu.h
+index a56053ff135af..da05f3e740810 100644
+--- a/drivers/media/platform/mediatek/vpu/mtk_vpu.h
++++ b/drivers/media/platform/mediatek/vpu/mtk_vpu.h
+@@ -17,7 +17,7 @@
+ * VPU interfaces with other blocks by share memory and interrupt.
+ */
+
+-typedef void (*ipi_handler_t) (const void *data,
++typedef void (*ipi_handler_t) (void *data,
+ unsigned int len,
+ void *priv);
+
+--
+2.43.0
+
--- /dev/null
+From a518701bc851d015df0d31ced331da62169d407b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Feb 2024 11:04:27 +0100
+Subject: media: pvrusb2: fix pvr2_stream_callback casts
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 30baa4a96b23add91a87305baaeba82c4e109e1f ]
+
+clang-16 complains about a control flow integrity (KCFI) issue in pvrusb2,
+which casts three different prototypes into pvr2_stream_callback:
+
+drivers/media/usb/pvrusb2/pvrusb2-v4l2.c:1070:30: error: cast from 'void (*)(struct pvr2_v4l2_fh *)' to 'pvr2_stream_callback' (aka 'void (*)(void *)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+ 1070 | pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+drivers/media/usb/pvrusb2/pvrusb2-context.c:110:6: error: cast from 'void (*)(struct pvr2_context *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+ 110 | (void (*)(void *))pvr2_context_notify,
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+drivers/media/usb/pvrusb2/pvrusb2-dvb.c:152:6: error: cast from 'void (*)(struct pvr2_dvb_adapter *)' to 'pvr2_stream_callback' (aka 'void (*)(void *)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+ 152 | (pvr2_stream_callback) pvr2_dvb_notify, adap);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Change the functions to actually take a void* argument so the cast is no longer
+needed.
+
+Fixes: bb8ce9d9143c ("V4L/DVB (7682): pvrusb2-dvb: finish up stream & buffer handling")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/pvrusb2/pvrusb2-context.c | 8 ++++----
+ drivers/media/usb/pvrusb2/pvrusb2-dvb.c | 6 ++++--
+ drivers/media/usb/pvrusb2/pvrusb2-v4l2.c | 6 ++++--
+ 3 files changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/media/usb/pvrusb2/pvrusb2-context.c b/drivers/media/usb/pvrusb2/pvrusb2-context.c
+index 1764674de98bc..58f2f3ff10ee2 100644
+--- a/drivers/media/usb/pvrusb2/pvrusb2-context.c
++++ b/drivers/media/usb/pvrusb2/pvrusb2-context.c
+@@ -90,8 +90,10 @@ static void pvr2_context_destroy(struct pvr2_context *mp)
+ }
+
+
+-static void pvr2_context_notify(struct pvr2_context *mp)
++static void pvr2_context_notify(void *ptr)
+ {
++ struct pvr2_context *mp = ptr;
++
+ pvr2_context_set_notify(mp,!0);
+ }
+
+@@ -106,9 +108,7 @@ static void pvr2_context_check(struct pvr2_context *mp)
+ pvr2_trace(PVR2_TRACE_CTXT,
+ "pvr2_context %p (initialize)", mp);
+ /* Finish hardware initialization */
+- if (pvr2_hdw_initialize(mp->hdw,
+- (void (*)(void *))pvr2_context_notify,
+- mp)) {
++ if (pvr2_hdw_initialize(mp->hdw, pvr2_context_notify, mp)) {
+ mp->video_stream.stream =
+ pvr2_hdw_get_video_stream(mp->hdw);
+ /* Trigger interface initialization. By doing this
+diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
+index 26811efe0fb58..9a9bae21c6147 100644
+--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
++++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
+@@ -88,8 +88,10 @@ static int pvr2_dvb_feed_thread(void *data)
+ return stat;
+ }
+
+-static void pvr2_dvb_notify(struct pvr2_dvb_adapter *adap)
++static void pvr2_dvb_notify(void *ptr)
+ {
++ struct pvr2_dvb_adapter *adap = ptr;
++
+ wake_up(&adap->buffer_wait_data);
+ }
+
+@@ -149,7 +151,7 @@ static int pvr2_dvb_stream_do_start(struct pvr2_dvb_adapter *adap)
+ }
+
+ pvr2_stream_set_callback(pvr->video_stream.stream,
+- (pvr2_stream_callback) pvr2_dvb_notify, adap);
++ pvr2_dvb_notify, adap);
+
+ ret = pvr2_stream_set_buffer_count(stream, PVR2_DVB_BUFFER_COUNT);
+ if (ret < 0) return ret;
+diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
+index d195bd6a2248b..d608b793fa847 100644
+--- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
++++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
+@@ -1033,8 +1033,10 @@ static int pvr2_v4l2_open(struct file *file)
+ }
+
+
+-static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp)
++static void pvr2_v4l2_notify(void *ptr)
+ {
++ struct pvr2_v4l2_fh *fhp = ptr;
++
+ wake_up(&fhp->wait_data);
+ }
+
+@@ -1067,7 +1069,7 @@ static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
+
+ hdw = fh->channel.mc_head->hdw;
+ sp = fh->pdi->stream->stream;
+- pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh);
++ pvr2_stream_set_callback(sp, pvr2_v4l2_notify, fh);
+ pvr2_hdw_set_stream_type(hdw,fh->pdi->config);
+ if ((ret = pvr2_hdw_set_streaming(hdw,!0)) < 0) return ret;
+ return pvr2_ioread_set_enabled(fh->rhp,!0);
+--
+2.43.0
+
--- /dev/null
+From 9d8ddaba7316543fcb729aee1a71f74f708b5340 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Feb 2024 15:30:47 +0800
+Subject: media: pvrusb2: fix uaf in pvr2_context_set_notify
+
+From: Edward Adam Davis <eadavis@qq.com>
+
+[ Upstream commit 0a0b79ea55de8514e1750884e5fec77f9fdd01ee ]
+
+[Syzbot reported]
+BUG: KASAN: slab-use-after-free in pvr2_context_set_notify+0x2c4/0x310 drivers/media/usb/pvrusb2/pvrusb2-context.c:35
+Read of size 4 at addr ffff888113aeb0d8 by task kworker/1:1/26
+
+CPU: 1 PID: 26 Comm: kworker/1:1 Not tainted 6.8.0-rc1-syzkaller-00046-gf1a27f081c1f #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/25/2024
+Workqueue: usb_hub_wq hub_event
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0xd9/0x1b0 lib/dump_stack.c:106
+ print_address_description mm/kasan/report.c:377 [inline]
+ print_report+0xc4/0x620 mm/kasan/report.c:488
+ kasan_report+0xda/0x110 mm/kasan/report.c:601
+ pvr2_context_set_notify+0x2c4/0x310 drivers/media/usb/pvrusb2/pvrusb2-context.c:35
+ pvr2_context_notify drivers/media/usb/pvrusb2/pvrusb2-context.c:95 [inline]
+ pvr2_context_disconnect+0x94/0xb0 drivers/media/usb/pvrusb2/pvrusb2-context.c:272
+
+Freed by task 906:
+kasan_save_stack+0x33/0x50 mm/kasan/common.c:47
+kasan_save_track+0x14/0x30 mm/kasan/common.c:68
+kasan_save_free_info+0x3f/0x60 mm/kasan/generic.c:640
+poison_slab_object mm/kasan/common.c:241 [inline]
+__kasan_slab_free+0x106/0x1b0 mm/kasan/common.c:257
+kasan_slab_free include/linux/kasan.h:184 [inline]
+slab_free_hook mm/slub.c:2121 [inline]
+slab_free mm/slub.c:4299 [inline]
+kfree+0x105/0x340 mm/slub.c:4409
+pvr2_context_check drivers/media/usb/pvrusb2/pvrusb2-context.c:137 [inline]
+pvr2_context_thread_func+0x69d/0x960 drivers/media/usb/pvrusb2/pvrusb2-context.c:158
+
+[Analyze]
+Task A set disconnect_flag = !0, which resulted in Task B's condition being met
+and releasing mp, leading to this issue.
+
+[Fix]
+Place the disconnect_flag assignment operation after all code in pvr2_context_disconnect()
+to avoid this issue.
+
+Reported-and-tested-by: syzbot+ce750e124675d4599449@syzkaller.appspotmail.com
+Fixes: e5be15c63804 ("V4L/DVB (7711): pvrusb2: Fix race on module unload")
+Signed-off-by: Edward Adam Davis <eadavis@qq.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/pvrusb2/pvrusb2-context.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/usb/pvrusb2/pvrusb2-context.c b/drivers/media/usb/pvrusb2/pvrusb2-context.c
+index 58f2f3ff10ee2..73c95ba2328a4 100644
+--- a/drivers/media/usb/pvrusb2/pvrusb2-context.c
++++ b/drivers/media/usb/pvrusb2/pvrusb2-context.c
+@@ -267,9 +267,9 @@ static void pvr2_context_exit(struct pvr2_context *mp)
+ void pvr2_context_disconnect(struct pvr2_context *mp)
+ {
+ pvr2_hdw_disconnect(mp->hdw);
+- mp->disconnect_flag = !0;
+ if (!pvr2_context_shutok())
+ pvr2_context_notify(mp);
++ mp->disconnect_flag = !0;
+ }
+
+
+--
+2.43.0
+
--- /dev/null
+From 1be310f5e450d76d2d9367492b28d1c215a79ba3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Feb 2024 07:07:25 -0800
+Subject: media: pvrusb2: remove redundant NULL check
+
+From: Daniil Dulov <d.dulov@aladdin.ru>
+
+[ Upstream commit 95ac1210fb2753f968ebce0730d4fbc553c2a3dc ]
+
+Pointer dip->stream cannot be NULL due to a shift, thus remove redundant
+NULL check.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: c74e0062684b ("V4L/DVB (5059): Pvrusb2: Be smarter about mode restoration")
+Signed-off-by: Daniil Dulov <d.dulov@aladdin.ru>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/pvrusb2/pvrusb2-v4l2.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
+index c04ab7258d645..d195bd6a2248b 100644
+--- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
++++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
+@@ -1198,11 +1198,6 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
+ dip->minor_type = pvr2_v4l_type_video;
+ nr_ptr = video_nr;
+ caps |= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO;
+- if (!dip->stream) {
+- pr_err(KBUILD_MODNAME
+- ": Failed to set up pvrusb2 v4l video dev due to missing stream instance\n");
+- return;
+- }
+ break;
+ case VFL_TYPE_VBI:
+ dip->config = pvr2_config_vbi;
+--
+2.43.0
+
--- /dev/null
+From f2cfbc9efc6d0622ec2e8c7766064aa305733aa3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 Dec 2023 14:34:22 +0100
+Subject: media: sun8i-di: Fix chroma difference threshold
+
+From: Jernej Skrabec <jernej.skrabec@gmail.com>
+
+[ Upstream commit 856525e8db272b0ce6d9c6e6c2eeb97892b485a6 ]
+
+While there is no good explanation what this value does, vendor driver
+uses value 31 for it. Align driver with it.
+
+Fixes: a4260ea49547 ("media: sun4i: Add H3 deinterlace driver")
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/sunxi/sun8i-di/sun8i-di.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
+index 01b44dd708bd3..7a2f558c981db 100644
+--- a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
++++ b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
+@@ -304,7 +304,7 @@ static void deinterlace_init(struct deinterlace_dev *dev)
+
+ deinterlace_clr_set_bits(dev, DEINTERLACE_CHROMA_DIFF,
+ DEINTERLACE_CHROMA_DIFF_TH_MSK,
+- DEINTERLACE_CHROMA_DIFF_TH(5));
++ DEINTERLACE_CHROMA_DIFF_TH(31));
+ }
+
+ static inline struct deinterlace_ctx *deinterlace_file2ctx(struct file *file)
+--
+2.43.0
+
--- /dev/null
+From 341415a998618a1d1a120cc9a95ff9d702fc179e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 Dec 2023 14:34:20 +0100
+Subject: media: sun8i-di: Fix coefficient writes
+
+From: Jernej Skrabec <jernej.skrabec@gmail.com>
+
+[ Upstream commit 794b581f8c6eb7b60fe468ccb96dd3cd38ff779f ]
+
+Currently coefficients are applied only once, since they don't change.
+However, this is done before enable bit is set and thus it doesn't get
+applied properly.
+
+Fix that by applying coefficients after enable bit is set. While this
+means that it will be done evey time, it doesn't bring much time
+penalty.
+
+Fixes: a4260ea49547 ("media: sun4i: Add H3 deinterlace driver")
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../media/platform/sunxi/sun8i-di/sun8i-di.c | 42 +++++++++----------
+ 1 file changed, 21 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
+index aa65d70b6270a..3e58de58cd89d 100644
+--- a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
++++ b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
+@@ -66,6 +66,7 @@ static void deinterlace_device_run(void *priv)
+ struct vb2_v4l2_buffer *src, *dst;
+ unsigned int hstep, vstep;
+ dma_addr_t addr;
++ int i;
+
+ src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+ dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+@@ -160,6 +161,26 @@ static void deinterlace_device_run(void *priv)
+ deinterlace_write(dev, DEINTERLACE_CH1_HORZ_FACT, hstep);
+ deinterlace_write(dev, DEINTERLACE_CH1_VERT_FACT, vstep);
+
++ /* neutral filter coefficients */
++ deinterlace_set_bits(dev, DEINTERLACE_FRM_CTRL,
++ DEINTERLACE_FRM_CTRL_COEF_ACCESS);
++ readl_poll_timeout(dev->base + DEINTERLACE_STATUS, val,
++ val & DEINTERLACE_STATUS_COEF_STATUS, 2, 40);
++
++ for (i = 0; i < 32; i++) {
++ deinterlace_write(dev, DEINTERLACE_CH0_HORZ_COEF0 + i * 4,
++ DEINTERLACE_IDENTITY_COEF);
++ deinterlace_write(dev, DEINTERLACE_CH0_VERT_COEF + i * 4,
++ DEINTERLACE_IDENTITY_COEF);
++ deinterlace_write(dev, DEINTERLACE_CH1_HORZ_COEF0 + i * 4,
++ DEINTERLACE_IDENTITY_COEF);
++ deinterlace_write(dev, DEINTERLACE_CH1_VERT_COEF + i * 4,
++ DEINTERLACE_IDENTITY_COEF);
++ }
++
++ deinterlace_clr_set_bits(dev, DEINTERLACE_FRM_CTRL,
++ DEINTERLACE_FRM_CTRL_COEF_ACCESS, 0);
++
+ deinterlace_clr_set_bits(dev, DEINTERLACE_FIELD_CTRL,
+ DEINTERLACE_FIELD_CTRL_FIELD_CNT_MSK,
+ DEINTERLACE_FIELD_CTRL_FIELD_CNT(ctx->field));
+@@ -248,7 +269,6 @@ static irqreturn_t deinterlace_irq(int irq, void *data)
+ static void deinterlace_init(struct deinterlace_dev *dev)
+ {
+ u32 val;
+- int i;
+
+ deinterlace_write(dev, DEINTERLACE_BYPASS,
+ DEINTERLACE_BYPASS_CSC);
+@@ -285,26 +305,6 @@ static void deinterlace_init(struct deinterlace_dev *dev)
+ deinterlace_clr_set_bits(dev, DEINTERLACE_CHROMA_DIFF,
+ DEINTERLACE_CHROMA_DIFF_TH_MSK,
+ DEINTERLACE_CHROMA_DIFF_TH(5));
+-
+- /* neutral filter coefficients */
+- deinterlace_set_bits(dev, DEINTERLACE_FRM_CTRL,
+- DEINTERLACE_FRM_CTRL_COEF_ACCESS);
+- readl_poll_timeout(dev->base + DEINTERLACE_STATUS, val,
+- val & DEINTERLACE_STATUS_COEF_STATUS, 2, 40);
+-
+- for (i = 0; i < 32; i++) {
+- deinterlace_write(dev, DEINTERLACE_CH0_HORZ_COEF0 + i * 4,
+- DEINTERLACE_IDENTITY_COEF);
+- deinterlace_write(dev, DEINTERLACE_CH0_VERT_COEF + i * 4,
+- DEINTERLACE_IDENTITY_COEF);
+- deinterlace_write(dev, DEINTERLACE_CH1_HORZ_COEF0 + i * 4,
+- DEINTERLACE_IDENTITY_COEF);
+- deinterlace_write(dev, DEINTERLACE_CH1_VERT_COEF + i * 4,
+- DEINTERLACE_IDENTITY_COEF);
+- }
+-
+- deinterlace_clr_set_bits(dev, DEINTERLACE_FRM_CTRL,
+- DEINTERLACE_FRM_CTRL_COEF_ACCESS, 0);
+ }
+
+ static inline struct deinterlace_ctx *deinterlace_file2ctx(struct file *file)
+--
+2.43.0
+
--- /dev/null
+From a4513e911839c01064a9b7cb4184cdbf7b806f84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 Dec 2023 14:34:21 +0100
+Subject: media: sun8i-di: Fix power on/off sequences
+
+From: Jernej Skrabec <jernej.skrabec@gmail.com>
+
+[ Upstream commit cff104e33bad38f4b2c8d58816a7accfaa2879f9 ]
+
+According to user manual, reset line should be deasserted before clocks
+are enabled. Also fix power down sequence to be reverse of that.
+
+Fixes: a4260ea49547 ("media: sun4i: Add H3 deinterlace driver")
+Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../media/platform/sunxi/sun8i-di/sun8i-di.c | 25 ++++++++++---------
+ 1 file changed, 13 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
+index 3e58de58cd89d..01b44dd708bd3 100644
+--- a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
++++ b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
+@@ -931,11 +931,18 @@ static int deinterlace_runtime_resume(struct device *device)
+ return ret;
+ }
+
++ ret = reset_control_deassert(dev->rstc);
++ if (ret) {
++ dev_err(dev->dev, "Failed to apply reset\n");
++
++ goto err_exclusive_rate;
++ }
++
+ ret = clk_prepare_enable(dev->bus_clk);
+ if (ret) {
+ dev_err(dev->dev, "Failed to enable bus clock\n");
+
+- goto err_exclusive_rate;
++ goto err_rst;
+ }
+
+ ret = clk_prepare_enable(dev->mod_clk);
+@@ -952,23 +959,16 @@ static int deinterlace_runtime_resume(struct device *device)
+ goto err_mod_clk;
+ }
+
+- ret = reset_control_deassert(dev->rstc);
+- if (ret) {
+- dev_err(dev->dev, "Failed to apply reset\n");
+-
+- goto err_ram_clk;
+- }
+-
+ deinterlace_init(dev);
+
+ return 0;
+
+-err_ram_clk:
+- clk_disable_unprepare(dev->ram_clk);
+ err_mod_clk:
+ clk_disable_unprepare(dev->mod_clk);
+ err_bus_clk:
+ clk_disable_unprepare(dev->bus_clk);
++err_rst:
++ reset_control_assert(dev->rstc);
+ err_exclusive_rate:
+ clk_rate_exclusive_put(dev->mod_clk);
+
+@@ -979,11 +979,12 @@ static int deinterlace_runtime_suspend(struct device *device)
+ {
+ struct deinterlace_dev *dev = dev_get_drvdata(device);
+
+- reset_control_assert(dev->rstc);
+-
+ clk_disable_unprepare(dev->ram_clk);
+ clk_disable_unprepare(dev->mod_clk);
+ clk_disable_unprepare(dev->bus_clk);
++
++ reset_control_assert(dev->rstc);
++
+ clk_rate_exclusive_put(dev->mod_clk);
+
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From e5a1bddd76b881ec1251d1c4e9f7836fb3b15213 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jan 2024 10:01:11 +0100
+Subject: media: tc358743: register v4l2 async device only after successful
+ setup
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit 87399f1ff92203d65f1febf5919429f4bb613a02 ]
+
+Ensure the device has been setup correctly before registering the v4l2
+async device, thus allowing userspace to access.
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Fixes: 4c5211a10039 ("[media] tc358743: register v4l2 asynchronous subdevice")
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240110090111.458115-1-alexander.stein@ew.tq-group.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/i2c/tc358743.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
+index 200841c1f5cf0..68628ccecd161 100644
+--- a/drivers/media/i2c/tc358743.c
++++ b/drivers/media/i2c/tc358743.c
+@@ -2094,9 +2094,6 @@ static int tc358743_probe(struct i2c_client *client)
+ state->mbus_fmt_code = MEDIA_BUS_FMT_RGB888_1X24;
+
+ sd->dev = &client->dev;
+- err = v4l2_async_register_subdev(sd);
+- if (err < 0)
+- goto err_hdl;
+
+ mutex_init(&state->confctl_mutex);
+
+@@ -2154,6 +2151,10 @@ static int tc358743_probe(struct i2c_client *client)
+ if (err)
+ goto err_work_queues;
+
++ err = v4l2_async_register_subdev(sd);
++ if (err < 0)
++ goto err_work_queues;
++
+ v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
+ client->addr << 1, client->adapter->name);
+
+--
+2.43.0
+
--- /dev/null
+From 04897d62d0ba2d5e98d83c80761adfff17fc3a7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Feb 2024 13:17:04 +0800
+Subject: media: ttpci: fix two memleaks in budget_av_attach
+
+From: Zhipeng Lu <alexious@zju.edu.cn>
+
+[ Upstream commit d0b07f712bf61e1a3cf23c87c663791c42e50837 ]
+
+When saa7146_register_device and saa7146_vv_init fails, budget_av_attach
+should free the resources it allocates, like the error-handling of
+ttpci_budget_init does. Besides, there are two fixme comment refers to
+such deallocations.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Zhipeng Lu <alexious@zju.edu.cn>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../staging/media/deprecated/saa7146/ttpci/budget-av.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/staging/media/deprecated/saa7146/ttpci/budget-av.c b/drivers/staging/media/deprecated/saa7146/ttpci/budget-av.c
+index 0c61a2dec2211..81fc4835679f3 100644
+--- a/drivers/staging/media/deprecated/saa7146/ttpci/budget-av.c
++++ b/drivers/staging/media/deprecated/saa7146/ttpci/budget-av.c
+@@ -1462,7 +1462,8 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
+ budget_av->has_saa7113 = 1;
+ err = saa7146_vv_init(dev, &vv_data);
+ if (err != 0) {
+- /* fixme: proper cleanup here */
++ ttpci_budget_deinit(&budget_av->budget);
++ kfree(budget_av);
+ ERR("cannot init vv subsystem\n");
+ return err;
+ }
+@@ -1471,9 +1472,10 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
+ vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
+
+ if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_VIDEO))) {
+- /* fixme: proper cleanup here */
+- ERR("cannot register capture v4l2 device\n");
+ saa7146_vv_release(dev);
++ ttpci_budget_deinit(&budget_av->budget);
++ kfree(budget_av);
++ ERR("cannot register capture v4l2 device\n");
+ return err;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 3e27f7372eb5dbc62371e5a7a8d3cea584a3f5a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Feb 2024 20:48:44 +0800
+Subject: media: v4l2-mem2mem: fix a memleak in v4l2_m2m_register_entity
+
+From: Zhipeng Lu <alexious@zju.edu.cn>
+
+[ Upstream commit 8f94b49a5b5d386c038e355bef6347298aabd211 ]
+
+The entity->name (i.e. name) is allocated in v4l2_m2m_register_entity
+but isn't freed in its following error-handling paths. This patch
+adds such deallocation to prevent memleak of entity->name.
+
+Fixes: be2fff656322 ("media: add helpers for memory-to-memory media controller")
+Signed-off-by: Zhipeng Lu <alexious@zju.edu.cn>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/v4l2-core/v4l2-mem2mem.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
+index be7fde1ed3eaa..97645d6509e1c 100644
+--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
++++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
+@@ -1084,11 +1084,17 @@ static int v4l2_m2m_register_entity(struct media_device *mdev,
+ entity->function = function;
+
+ ret = media_entity_pads_init(entity, num_pads, pads);
+- if (ret)
++ if (ret) {
++ kfree(entity->name);
++ entity->name = NULL;
+ return ret;
++ }
+ ret = media_device_register_entity(mdev, entity);
+- if (ret)
++ if (ret) {
++ kfree(entity->name);
++ entity->name = NULL;
+ return ret;
++ }
+
+ return 0;
+ }
+--
+2.43.0
+
--- /dev/null
+From 19e809d0a45f569b7c19058d0b157993d5704ed4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Feb 2024 20:47:53 +0800
+Subject: media: v4l2-tpg: fix some memleaks in tpg_alloc
+
+From: Zhipeng Lu <alexious@zju.edu.cn>
+
+[ Upstream commit 8cf9c5051076e0eb958f4361d50d8b0c3ee6691c ]
+
+In tpg_alloc, resources should be deallocated in each and every
+error-handling paths, since they are allocated in for statements.
+Otherwise there would be memleaks because tpg_free is called only when
+tpg_alloc return 0.
+
+Fixes: 63881df94d3e ("[media] vivid: add the Test Pattern Generator")
+Signed-off-by: Zhipeng Lu <alexious@zju.edu.cn>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/common/v4l2-tpg/v4l2-tpg-core.c | 52 +++++++++++++++----
+ 1 file changed, 42 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
+index 303d02b1d71c9..fe30f5b0050dd 100644
+--- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
++++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
+@@ -113,6 +113,7 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
+ {
+ unsigned pat;
+ unsigned plane;
++ int ret = 0;
+
+ tpg->max_line_width = max_w;
+ for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) {
+@@ -121,14 +122,18 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
+
+ tpg->lines[pat][plane] =
+ vzalloc(array3_size(max_w, 2, pixelsz));
+- if (!tpg->lines[pat][plane])
+- return -ENOMEM;
++ if (!tpg->lines[pat][plane]) {
++ ret = -ENOMEM;
++ goto free_lines;
++ }
+ if (plane == 0)
+ continue;
+ tpg->downsampled_lines[pat][plane] =
+ vzalloc(array3_size(max_w, 2, pixelsz));
+- if (!tpg->downsampled_lines[pat][plane])
+- return -ENOMEM;
++ if (!tpg->downsampled_lines[pat][plane]) {
++ ret = -ENOMEM;
++ goto free_lines;
++ }
+ }
+ }
+ for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
+@@ -136,18 +141,45 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
+
+ tpg->contrast_line[plane] =
+ vzalloc(array_size(pixelsz, max_w));
+- if (!tpg->contrast_line[plane])
+- return -ENOMEM;
++ if (!tpg->contrast_line[plane]) {
++ ret = -ENOMEM;
++ goto free_contrast_line;
++ }
+ tpg->black_line[plane] =
+ vzalloc(array_size(pixelsz, max_w));
+- if (!tpg->black_line[plane])
+- return -ENOMEM;
++ if (!tpg->black_line[plane]) {
++ ret = -ENOMEM;
++ goto free_contrast_line;
++ }
+ tpg->random_line[plane] =
+ vzalloc(array3_size(max_w, 2, pixelsz));
+- if (!tpg->random_line[plane])
+- return -ENOMEM;
++ if (!tpg->random_line[plane]) {
++ ret = -ENOMEM;
++ goto free_contrast_line;
++ }
+ }
+ return 0;
++
++free_contrast_line:
++ for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
++ vfree(tpg->contrast_line[plane]);
++ vfree(tpg->black_line[plane]);
++ vfree(tpg->random_line[plane]);
++ tpg->contrast_line[plane] = NULL;
++ tpg->black_line[plane] = NULL;
++ tpg->random_line[plane] = NULL;
++ }
++free_lines:
++ for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++)
++ for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
++ vfree(tpg->lines[pat][plane]);
++ tpg->lines[pat][plane] = NULL;
++ if (plane == 0)
++ continue;
++ vfree(tpg->downsampled_lines[pat][plane]);
++ tpg->downsampled_lines[pat][plane] = NULL;
++ }
++ return ret;
+ }
+ EXPORT_SYMBOL_GPL(tpg_alloc);
+
+--
+2.43.0
+
--- /dev/null
+From 33720350d6a5a9d859659c457f1832c036eb3334 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Feb 2024 11:50:12 +0000
+Subject: mfd: altera-sysmgr: Call of_node_put() only when of_parse_phandle()
+ takes a ref
+
+From: Peter Griffin <peter.griffin@linaro.org>
+
+[ Upstream commit e28c28a34ee9fa2ea671a20e5e7064e6220d55e7 ]
+
+of_parse_phandle() returns a device_node with refcount incremented, which
+the callee needs to call of_node_put() on when done. We should only call
+of_node_put() when the property argument is provided though as otherwise
+nothing has taken a reference on the node.
+
+Fixes: f36e789a1f8d ("mfd: altera-sysmgr: Add SOCFPGA System Manager")
+Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
+Link: https://lore.kernel.org/r/20240220115012.471689-4-peter.griffin@linaro.org
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/altera-sysmgr.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mfd/altera-sysmgr.c b/drivers/mfd/altera-sysmgr.c
+index 5d3715a28b28e..dbe1009943718 100644
+--- a/drivers/mfd/altera-sysmgr.c
++++ b/drivers/mfd/altera-sysmgr.c
+@@ -110,7 +110,9 @@ struct regmap *altr_sysmgr_regmap_lookup_by_phandle(struct device_node *np,
+
+ dev = driver_find_device_by_of_node(&altr_sysmgr_driver.driver,
+ (void *)sysmgr_np);
+- of_node_put(sysmgr_np);
++ if (property)
++ of_node_put(sysmgr_np);
++
+ if (!dev)
+ return ERR_PTR(-EPROBE_DEFER);
+
+--
+2.43.0
+
--- /dev/null
+From 5ace08ccd361fd0e7d261472c9abc1b1dd6ec503 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Feb 2024 11:50:10 +0000
+Subject: mfd: syscon: Call of_node_put() only when of_parse_phandle() takes a
+ ref
+
+From: Peter Griffin <peter.griffin@linaro.org>
+
+[ Upstream commit d2b0680cf3b05490b579e71b0df6e07451977745 ]
+
+of_parse_phandle() returns a device_node with refcount incremented, which
+the callee needs to call of_node_put() on when done. We should only call
+of_node_put() when the property argument is provided though as otherwise
+nothing has taken a reference on the node.
+
+Fixes: 45330bb43421 ("mfd: syscon: Allow property as NULL in syscon_regmap_lookup_by_phandle")
+Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
+Link: https://lore.kernel.org/r/20240220115012.471689-2-peter.griffin@linaro.org
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/syscon.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
+index 6196724ef39bb..ecfe151220919 100644
+--- a/drivers/mfd/syscon.c
++++ b/drivers/mfd/syscon.c
+@@ -223,7 +223,9 @@ struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np,
+ return ERR_PTR(-ENODEV);
+
+ regmap = syscon_node_to_regmap(syscon_np);
+- of_node_put(syscon_np);
++
++ if (property)
++ of_node_put(syscon_np);
+
+ return regmap;
+ }
+--
+2.43.0
+
--- /dev/null
+From 72a9bc48f6fac87117882fca42d7c093448e87c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Feb 2024 22:37:39 +0100
+Subject: mmc: wmt-sdmmc: remove an incorrect release_mem_region() call in the
+ .remove function
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit ae5004a40a262d329039b99b62bd3fe7645b66ad ]
+
+This looks strange to call release_mem_region() in a remove function
+without any request_mem_region() in the probe or "struct resource"
+somewhere.
+
+So remove the corresponding code.
+
+Fixes: 3a96dff0f828 ("mmc: SD/MMC Host Controller for Wondermedia WM8505/WM8650")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/bb0bb1ed1e18de55e8c0547625bde271e64b8c31.1708983064.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/wmt-sdmmc.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c
+index 9aa3027ca25e4..f2abebb2d8574 100644
+--- a/drivers/mmc/host/wmt-sdmmc.c
++++ b/drivers/mmc/host/wmt-sdmmc.c
+@@ -886,7 +886,6 @@ static int wmt_mci_remove(struct platform_device *pdev)
+ {
+ struct mmc_host *mmc;
+ struct wmt_mci_priv *priv;
+- struct resource *res;
+ u32 reg_tmp;
+
+ mmc = platform_get_drvdata(pdev);
+@@ -914,9 +913,6 @@ static int wmt_mci_remove(struct platform_device *pdev)
+ clk_disable_unprepare(priv->clk_sdmmc);
+ clk_put(priv->clk_sdmmc);
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- release_mem_region(res->start, resource_size(res));
+-
+ mmc_free_host(mmc);
+
+ dev_info(&pdev->dev, "WMT MCI device removed\n");
+--
+2.43.0
+
--- /dev/null
+From 1e9dba6ae9623616b436039b1c267ad5f8963795 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Feb 2024 10:35:46 +0800
+Subject: modules: wait do_free_init correctly
+
+From: Changbin Du <changbin.du@huawei.com>
+
+[ Upstream commit 8f8cd6c0a43ed637e620bbe45a8d0e0c2f4d5130 ]
+
+The synchronization here is to ensure the ordering of freeing of a module
+init so that it happens before W+X checking. It is worth noting it is not
+that the freeing was not happening, it is just that our sanity checkers
+raced against the permission checkers which assume init memory is already
+gone.
+
+Commit 1a7b7d922081 ("modules: Use vmalloc special flag") moved calling
+do_free_init() into a global workqueue instead of relying on it being
+called through call_rcu(..., do_free_init), which used to allowed us call
+do_free_init() asynchronously after the end of a subsequent grace period.
+The move to a global workqueue broke the gaurantees for code which needed
+to be sure the do_free_init() would complete with rcu_barrier(). To fix
+this callers which used to rely on rcu_barrier() must now instead use
+flush_work(&init_free_wq).
+
+Without this fix, we still could encounter false positive reports in W+X
+checking since the rcu_barrier() here can not ensure the ordering now.
+
+Even worse, the rcu_barrier() can introduce significant delay. Eric
+Chanudet reported that the rcu_barrier introduces ~0.1s delay on a
+PREEMPT_RT kernel.
+
+ [ 0.291444] Freeing unused kernel memory: 5568K
+ [ 0.402442] Run /sbin/init as init process
+
+With this fix, the above delay can be eliminated.
+
+Link: https://lkml.kernel.org/r/20240227023546.2490667-1-changbin.du@huawei.com
+Fixes: 1a7b7d922081 ("modules: Use vmalloc special flag")
+Signed-off-by: Changbin Du <changbin.du@huawei.com>
+Tested-by: Eric Chanudet <echanude@redhat.com>
+Acked-by: Luis Chamberlain <mcgrof@kernel.org>
+Cc: Xiaoyi Su <suxiaoyi@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/moduleloader.h | 8 ++++++++
+ init/main.c | 5 +++--
+ kernel/module/main.c | 9 +++++++--
+ 3 files changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h
+index 1322652a9d0d9..7dc186ec52a29 100644
+--- a/include/linux/moduleloader.h
++++ b/include/linux/moduleloader.h
+@@ -95,6 +95,14 @@ int module_finalize(const Elf_Ehdr *hdr,
+ const Elf_Shdr *sechdrs,
+ struct module *mod);
+
++#ifdef CONFIG_MODULES
++void flush_module_init_free_work(void);
++#else
++static inline void flush_module_init_free_work(void)
++{
++}
++#endif
++
+ /* Any cleanup needed when module leaves. */
+ void module_arch_cleanup(struct module *mod);
+
+diff --git a/init/main.c b/init/main.c
+index 87a52bdb41d67..ccde19e7275fa 100644
+--- a/init/main.c
++++ b/init/main.c
+@@ -89,6 +89,7 @@
+ #include <linux/sched/task_stack.h>
+ #include <linux/context_tracking.h>
+ #include <linux/random.h>
++#include <linux/moduleloader.h>
+ #include <linux/list.h>
+ #include <linux/integrity.h>
+ #include <linux/proc_ns.h>
+@@ -1473,11 +1474,11 @@ static void mark_readonly(void)
+ if (rodata_enabled) {
+ /*
+ * load_module() results in W+X mappings, which are cleaned
+- * up with call_rcu(). Let's make sure that queued work is
++ * up with init_free_wq. Let's make sure that queued work is
+ * flushed so that we don't hit false positives looking for
+ * insecure pages which are W+X.
+ */
+- rcu_barrier();
++ flush_module_init_free_work();
+ mark_rodata_ro();
+ rodata_test();
+ } else
+diff --git a/kernel/module/main.c b/kernel/module/main.c
+index 7a376e26de85b..554aba47ab689 100644
+--- a/kernel/module/main.c
++++ b/kernel/module/main.c
+@@ -2434,6 +2434,11 @@ static void do_free_init(struct work_struct *w)
+ }
+ }
+
++void flush_module_init_free_work(void)
++{
++ flush_work(&init_free_wq);
++}
++
+ #undef MODULE_PARAM_PREFIX
+ #define MODULE_PARAM_PREFIX "module."
+ /* Default value for module->async_probe_requested */
+@@ -2524,8 +2529,8 @@ static noinline int do_init_module(struct module *mod)
+ * Note that module_alloc() on most architectures creates W+X page
+ * mappings which won't be cleaned up until do_free_init() runs. Any
+ * code such as mark_rodata_ro() which depends on those mappings to
+- * be cleaned up needs to sync with the queued work - ie
+- * rcu_barrier()
++ * be cleaned up needs to sync with the queued work by invoking
++ * flush_module_init_free_work().
+ */
+ if (llist_add(&freeinit->node, &init_free_list))
+ schedule_work(&init_free_wq);
+--
+2.43.0
+
--- /dev/null
+From deb3d68618e8e9746fc057145828e3813c27195b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Feb 2024 12:34:18 +0200
+Subject: mtd: maps: physmap-core: fix flash size larger than 32-bit
+
+From: Baruch Siach <baruch@tkos.co.il>
+
+[ Upstream commit 3884f03edd34887514a0865a80769cd5362d5c3b ]
+
+mtd-ram can potentially be larger than 4GB. get_bitmask_order() uses
+fls() that is not guaranteed to work with values larger than 32-bit.
+Specifically on aarch64 fls() returns 0 when all 32 LSB bits are clear.
+Use fls64() instead.
+
+Fixes: ba32ce95cbd987 ("mtd: maps: Merge gpio-addr-flash.c into physmap-core.c")
+Signed-off-by: Baruch Siach <baruch@tkos.co.il>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/9fbf3664ce00f8b07867f1011834015f21d162a5.1707388458.git.baruch@tkos.co.il
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/maps/physmap-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/maps/physmap-core.c b/drivers/mtd/maps/physmap-core.c
+index 19dad5a23f944..8cdb3512107d3 100644
+--- a/drivers/mtd/maps/physmap-core.c
++++ b/drivers/mtd/maps/physmap-core.c
+@@ -524,7 +524,7 @@ static int physmap_flash_probe(struct platform_device *dev)
+ if (!info->maps[i].phys)
+ info->maps[i].phys = res->start;
+
+- info->win_order = get_bitmask_order(resource_size(res)) - 1;
++ info->win_order = fls64(resource_size(res)) - 1;
+ info->maps[i].size = BIT(info->win_order +
+ (info->gpios ?
+ info->gpios->ndescs : 0));
+--
+2.43.0
+
--- /dev/null
+From 0f6eee933c18d44d680f299586df3c4b46307ad0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Feb 2024 11:00:09 +0100
+Subject: mtd: rawnand: lpc32xx_mlc: fix irq handler prototype
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 347b828882e6334690e7003ce5e2fe5f233dc508 ]
+
+clang-16 warns about mismatched function prototypes:
+
+drivers/mtd/nand/raw/lpc32xx_mlc.c:783:29: error: cast from 'irqreturn_t (*)(int, struct lpc32xx_nand_host *)' (aka 'enum irqreturn (*)(int, struct lpc32xx_nand_host *)') to 'irq_handler_t' (aka 'enum irqreturn (*)(int, void *)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+
+Change the interrupt handler to the normal way of just passing
+a void* pointer and converting it inside the function..
+
+Fixes: 70f7cb78ec53 ("mtd: add LPC32xx MLC NAND driver")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20240213100146.455811-1-arnd@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/raw/lpc32xx_mlc.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mtd/nand/raw/lpc32xx_mlc.c b/drivers/mtd/nand/raw/lpc32xx_mlc.c
+index 452ecaf7775ac..1cfe3dd0bad4d 100644
+--- a/drivers/mtd/nand/raw/lpc32xx_mlc.c
++++ b/drivers/mtd/nand/raw/lpc32xx_mlc.c
+@@ -303,8 +303,9 @@ static int lpc32xx_nand_device_ready(struct nand_chip *nand_chip)
+ return 0;
+ }
+
+-static irqreturn_t lpc3xxx_nand_irq(int irq, struct lpc32xx_nand_host *host)
++static irqreturn_t lpc3xxx_nand_irq(int irq, void *data)
+ {
++ struct lpc32xx_nand_host *host = data;
+ uint8_t sr;
+
+ /* Clear interrupt flag by reading status */
+@@ -779,7 +780,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
+ goto release_dma_chan;
+ }
+
+- if (request_irq(host->irq, (irq_handler_t)&lpc3xxx_nand_irq,
++ if (request_irq(host->irq, &lpc3xxx_nand_irq,
+ IRQF_TRIGGER_HIGH, DRV_NAME, host)) {
+ dev_err(&pdev->dev, "Error requesting NAND IRQ\n");
+ res = -ENXIO;
+--
+2.43.0
+
--- /dev/null
+From 5c606933119eb28145ffb60604f729fe5498e46f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Feb 2024 20:25:38 -0800
+Subject: nbd: null check for nla_nest_start
+
+From: Navid Emamdoost <navid.emamdoost@gmail.com>
+
+[ Upstream commit 31edf4bbe0ba27fd03ac7d87eb2ee3d2a231af6d ]
+
+nla_nest_start() may fail and return NULL. Insert a check and set errno
+based on other call sites within the same source code.
+
+Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
+Reviewed-by: Michal Kubecek <mkubecek@suse.cz>
+Fixes: 47d902b90a32 ("nbd: add a status netlink command")
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20240218042534.it.206-kees@kernel.org
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/nbd.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
+index 9a53165de4cef..5c4be8dda253c 100644
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -2408,6 +2408,12 @@ static int nbd_genl_status(struct sk_buff *skb, struct genl_info *info)
+ }
+
+ dev_list = nla_nest_start_noflag(reply, NBD_ATTR_DEVICE_LIST);
++ if (!dev_list) {
++ nlmsg_free(reply);
++ ret = -EMSGSIZE;
++ goto out;
++ }
++
+ if (index == -1) {
+ ret = idr_for_each(&nbd_index_idr, &status_cb, reply);
+ if (ret) {
+--
+2.43.0
+
--- /dev/null
+From 9bebd19d4ec54e9e340262d2e4ec0edd6c475b96 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Feb 2024 07:13:29 -0800
+Subject: net: blackhole_dev: fix build warning for ethh set but not used
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 843a8851e89e2e85db04caaf88d8554818319047 ]
+
+lib/test_blackhole_dev.c sets a variable that is never read, causing
+this following building warning:
+
+ lib/test_blackhole_dev.c:32:17: warning: variable 'ethh' set but not used [-Wunused-but-set-variable]
+
+Remove the variable struct ethhdr *ethh, which is unused.
+
+Fixes: 509e56b37cc3 ("blackhole_dev: add a selftest")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/test_blackhole_dev.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/lib/test_blackhole_dev.c b/lib/test_blackhole_dev.c
+index 4c40580a99a36..f247089d63c08 100644
+--- a/lib/test_blackhole_dev.c
++++ b/lib/test_blackhole_dev.c
+@@ -29,7 +29,6 @@ static int __init test_blackholedev_init(void)
+ {
+ struct ipv6hdr *ip6h;
+ struct sk_buff *skb;
+- struct ethhdr *ethh;
+ struct udphdr *uh;
+ int data_len;
+ int ret;
+@@ -61,7 +60,7 @@ static int __init test_blackholedev_init(void)
+ ip6h->saddr = in6addr_loopback;
+ ip6h->daddr = in6addr_loopback;
+ /* Ether */
+- ethh = (struct ethhdr *)skb_push(skb, sizeof(struct ethhdr));
++ skb_push(skb, sizeof(struct ethhdr));
+ skb_set_mac_header(skb, 0);
+
+ skb->protocol = htons(ETH_P_IPV6);
+--
+2.43.0
+
--- /dev/null
+From ffbd23dd336f9c8008e98b247316a2f11a1b1e35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Feb 2024 17:31:04 -0500
+Subject: net: ena: Remove ena_select_queue
+
+From: Kamal Heib <kheib@redhat.com>
+
+[ Upstream commit 78e886ba2b549945ecada055ee0765f0ded5707a ]
+
+Avoid the following warnings by removing the ena_select_queue() function
+and rely on the net core to do the queue selection, The issue happen
+when an skb received from an interface with more queues than ena is
+forwarded to the ena interface.
+
+[ 1176.159959] eth0 selects TX queue 11, but real number of TX queues is 8
+[ 1176.863976] eth0 selects TX queue 14, but real number of TX queues is 8
+[ 1180.767877] eth0 selects TX queue 14, but real number of TX queues is 8
+[ 1188.703742] eth0 selects TX queue 14, but real number of TX queues is 8
+
+Fixes: 1738cd3ed342 ("net: ena: Add a driver for Amazon Elastic Network Adapters (ENA)")
+Signed-off-by: Kamal Heib <kheib@redhat.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 17 -----------------
+ 1 file changed, 17 deletions(-)
+
+diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+index 044b8afde69a0..9e82e7b9c3b72 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -3174,22 +3174,6 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ return NETDEV_TX_OK;
+ }
+
+-static u16 ena_select_queue(struct net_device *dev, struct sk_buff *skb,
+- struct net_device *sb_dev)
+-{
+- u16 qid;
+- /* we suspect that this is good for in--kernel network services that
+- * want to loop incoming skb rx to tx in normal user generated traffic,
+- * most probably we will not get to this
+- */
+- if (skb_rx_queue_recorded(skb))
+- qid = skb_get_rx_queue(skb);
+- else
+- qid = netdev_pick_tx(dev, skb, NULL);
+-
+- return qid;
+-}
+-
+ static void ena_config_host_info(struct ena_com_dev *ena_dev, struct pci_dev *pdev)
+ {
+ struct device *dev = &pdev->dev;
+@@ -3359,7 +3343,6 @@ static const struct net_device_ops ena_netdev_ops = {
+ .ndo_open = ena_open,
+ .ndo_stop = ena_close,
+ .ndo_start_xmit = ena_start_xmit,
+- .ndo_select_queue = ena_select_queue,
+ .ndo_get_stats64 = ena_get_stats64,
+ .ndo_tx_timeout = ena_tx_timeout,
+ .ndo_change_mtu = ena_change_mtu,
+--
+2.43.0
+
--- /dev/null
+From a308d72022b6a32ac6c4a2daeec57eed1a111754 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 09:01:11 +0800
+Subject: net: hns3: fix kernel crash when 1588 is received on HIP08 devices
+
+From: Yonglong Liu <liuyonglong@huawei.com>
+
+[ Upstream commit 0fbcf2366ba9888cf02eda23e35fde7f7fcc07c3 ]
+
+The HIP08 devices does not register the ptp devices, so the
+hdev->ptp is NULL, but the hardware can receive 1588 messages,
+and set the HNS3_RXD_TS_VLD_B bit, so, if match this case, the
+access of hdev->ptp->flags will cause a kernel crash:
+
+[ 5888.946472] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000018
+[ 5888.946475] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000018
+...
+[ 5889.266118] pc : hclge_ptp_get_rx_hwts+0x40/0x170 [hclge]
+[ 5889.272612] lr : hclge_ptp_get_rx_hwts+0x34/0x170 [hclge]
+[ 5889.279101] sp : ffff800012c3bc50
+[ 5889.283516] x29: ffff800012c3bc50 x28: ffff2040002be040
+[ 5889.289927] x27: ffff800009116484 x26: 0000000080007500
+[ 5889.296333] x25: 0000000000000000 x24: ffff204001c6f000
+[ 5889.302738] x23: ffff204144f53c00 x22: 0000000000000000
+[ 5889.309134] x21: 0000000000000000 x20: ffff204004220080
+[ 5889.315520] x19: ffff204144f53c00 x18: 0000000000000000
+[ 5889.321897] x17: 0000000000000000 x16: 0000000000000000
+[ 5889.328263] x15: 0000004000140ec8 x14: 0000000000000000
+[ 5889.334617] x13: 0000000000000000 x12: 00000000010011df
+[ 5889.340965] x11: bbfeff4d22000000 x10: 0000000000000000
+[ 5889.347303] x9 : ffff800009402124 x8 : 0200f78811dfbb4d
+[ 5889.353637] x7 : 2200000000191b01 x6 : ffff208002a7d480
+[ 5889.359959] x5 : 0000000000000000 x4 : 0000000000000000
+[ 5889.366271] x3 : 0000000000000000 x2 : 0000000000000000
+[ 5889.372567] x1 : 0000000000000000 x0 : ffff20400095c080
+[ 5889.378857] Call trace:
+[ 5889.382285] hclge_ptp_get_rx_hwts+0x40/0x170 [hclge]
+[ 5889.388304] hns3_handle_bdinfo+0x324/0x410 [hns3]
+[ 5889.394055] hns3_handle_rx_bd+0x60/0x150 [hns3]
+[ 5889.399624] hns3_clean_rx_ring+0x84/0x170 [hns3]
+[ 5889.405270] hns3_nic_common_poll+0xa8/0x220 [hns3]
+[ 5889.411084] napi_poll+0xcc/0x264
+[ 5889.415329] net_rx_action+0xd4/0x21c
+[ 5889.419911] __do_softirq+0x130/0x358
+[ 5889.424484] irq_exit+0x134/0x154
+[ 5889.428700] __handle_domain_irq+0x88/0xf0
+[ 5889.433684] gic_handle_irq+0x78/0x2c0
+[ 5889.438319] el1_irq+0xb8/0x140
+[ 5889.442354] arch_cpu_idle+0x18/0x40
+[ 5889.446816] default_idle_call+0x5c/0x1c0
+[ 5889.451714] cpuidle_idle_call+0x174/0x1b0
+[ 5889.456692] do_idle+0xc8/0x160
+[ 5889.460717] cpu_startup_entry+0x30/0xfc
+[ 5889.465523] secondary_start_kernel+0x158/0x1ec
+[ 5889.470936] Code: 97ffab78 f9411c14 91408294 f9457284 (f9400c80)
+[ 5889.477950] SMP: stopping secondary CPUs
+[ 5890.514626] SMP: failed to stop secondary CPUs 0-69,71-95
+[ 5890.522951] Starting crashdump kernel...
+
+Fixes: 0bf5eb788512 ("net: hns3: add support for PTP")
+Signed-off-by: Yonglong Liu <liuyonglong@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c
+index a40b1583f1149..0f06f95b09bc2 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c
+@@ -120,7 +120,7 @@ void hclge_ptp_get_rx_hwts(struct hnae3_handle *handle, struct sk_buff *skb,
+ u64 ns = nsec;
+ u32 sec_h;
+
+- if (!test_bit(HCLGE_PTP_FLAG_RX_EN, &hdev->ptp->flags))
++ if (!hdev->ptp || !test_bit(HCLGE_PTP_FLAG_RX_EN, &hdev->ptp->flags))
+ return;
+
+ /* Since the BD does not have enough space for the higher 16 bits of
+--
+2.43.0
+
--- /dev/null
+From 4e375d73b8b7ff350d7d8e107b7ad0b982213252 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 09:01:14 +0800
+Subject: net: hns3: fix port duplex configure error in IMP reset
+
+From: Jie Wang <wangjie125@huawei.com>
+
+[ Upstream commit 11d80f79dd9f871a52feba4bf24b5ac39f448eb7 ]
+
+Currently, the mac port is fixed to configured as full dplex mode in
+hclge_mac_init() when driver initialization or reset restore. Users may
+change the mode to half duplex with ethtool, so it may cause the user
+configuration dropped after reset.
+
+To fix it, don't change the duplex mode when resetting.
+
+Fixes: 2d03eacc0b7e ("net: hns3: Only update mac configuation when necessary")
+Signed-off-by: Jie Wang <wangjie125@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index 48b0cb5ec5d29..27037ce795902 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -2990,7 +2990,10 @@ static int hclge_mac_init(struct hclge_dev *hdev)
+ int ret;
+
+ hdev->support_sfp_query = true;
+- hdev->hw.mac.duplex = HCLGE_MAC_FULL;
++
++ if (!test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state))
++ hdev->hw.mac.duplex = HCLGE_MAC_FULL;
++
+ ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.speed,
+ hdev->hw.mac.duplex, hdev->hw.mac.lane_num);
+ if (ret)
+--
+2.43.0
+
--- /dev/null
+From 5c0d8ac1bf0fc1a0e167a40cc5561787e8678ed6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 09:01:08 +0800
+Subject: net: hns3: fix wrong judgment condition issue
+
+From: Jijie Shao <shaojijie@huawei.com>
+
+[ Upstream commit 07a1d6dc90baedcf5d713e2b003b9e387130ee30 ]
+
+In hns3_dcbnl_ieee_delapp, should check ieee_delapp not ieee_setapp.
+This path fix the wrong judgment.
+
+Fixes: 0ba22bcb222d ("net: hns3: add support config dscp map to tc")
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3_dcbnl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_dcbnl.c b/drivers/net/ethernet/hisilicon/hns3/hns3_dcbnl.c
+index 3b6dbf158b98d..f72dc0cee30e5 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_dcbnl.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_dcbnl.c
+@@ -76,7 +76,7 @@ static int hns3_dcbnl_ieee_delapp(struct net_device *ndev, struct dcb_app *app)
+ if (hns3_nic_resetting(ndev))
+ return -EBUSY;
+
+- if (h->kinfo.dcb_ops->ieee_setapp)
++ if (h->kinfo.dcb_ops->ieee_delapp)
+ return h->kinfo.dcb_ops->ieee_delapp(h, app);
+
+ return -EOPNOTSUPP;
+--
+2.43.0
+
--- /dev/null
+From 9b9426e01f7d82986c1f5ba0835627a37e96b52c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 10:07:16 +0000
+Subject: net: ip_tunnel: make sure to pull inner header in ip_tunnel_rcv()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b0ec2abf98267f14d032102551581c833b0659d3 ]
+
+Apply the same fix than ones found in :
+
+8d975c15c0cd ("ip6_tunnel: make sure to pull inner header in __ip6_tnl_rcv()")
+1ca1ba465e55 ("geneve: make sure to pull inner header in geneve_rx()")
+
+We have to save skb->network_header in a temporary variable
+in order to be able to recompute the network_header pointer
+after a pskb_inet_may_pull() call.
+
+pskb_inet_may_pull() makes sure the needed headers are in skb->head.
+
+syzbot reported:
+BUG: KMSAN: uninit-value in __INET_ECN_decapsulate include/net/inet_ecn.h:253 [inline]
+ BUG: KMSAN: uninit-value in INET_ECN_decapsulate include/net/inet_ecn.h:275 [inline]
+ BUG: KMSAN: uninit-value in IP_ECN_decapsulate include/net/inet_ecn.h:302 [inline]
+ BUG: KMSAN: uninit-value in ip_tunnel_rcv+0xed9/0x2ed0 net/ipv4/ip_tunnel.c:409
+ __INET_ECN_decapsulate include/net/inet_ecn.h:253 [inline]
+ INET_ECN_decapsulate include/net/inet_ecn.h:275 [inline]
+ IP_ECN_decapsulate include/net/inet_ecn.h:302 [inline]
+ ip_tunnel_rcv+0xed9/0x2ed0 net/ipv4/ip_tunnel.c:409
+ __ipgre_rcv+0x9bc/0xbc0 net/ipv4/ip_gre.c:389
+ ipgre_rcv net/ipv4/ip_gre.c:411 [inline]
+ gre_rcv+0x423/0x19f0 net/ipv4/ip_gre.c:447
+ gre_rcv+0x2a4/0x390 net/ipv4/gre_demux.c:163
+ ip_protocol_deliver_rcu+0x264/0x1300 net/ipv4/ip_input.c:205
+ ip_local_deliver_finish+0x2b8/0x440 net/ipv4/ip_input.c:233
+ NF_HOOK include/linux/netfilter.h:314 [inline]
+ ip_local_deliver+0x21f/0x490 net/ipv4/ip_input.c:254
+ dst_input include/net/dst.h:461 [inline]
+ ip_rcv_finish net/ipv4/ip_input.c:449 [inline]
+ NF_HOOK include/linux/netfilter.h:314 [inline]
+ ip_rcv+0x46f/0x760 net/ipv4/ip_input.c:569
+ __netif_receive_skb_one_core net/core/dev.c:5534 [inline]
+ __netif_receive_skb+0x1a6/0x5a0 net/core/dev.c:5648
+ netif_receive_skb_internal net/core/dev.c:5734 [inline]
+ netif_receive_skb+0x58/0x660 net/core/dev.c:5793
+ tun_rx_batched+0x3ee/0x980 drivers/net/tun.c:1556
+ tun_get_user+0x53b9/0x66e0 drivers/net/tun.c:2009
+ tun_chr_write_iter+0x3af/0x5d0 drivers/net/tun.c:2055
+ call_write_iter include/linux/fs.h:2087 [inline]
+ new_sync_write fs/read_write.c:497 [inline]
+ vfs_write+0xb6b/0x1520 fs/read_write.c:590
+ ksys_write+0x20f/0x4c0 fs/read_write.c:643
+ __do_sys_write fs/read_write.c:655 [inline]
+ __se_sys_write fs/read_write.c:652 [inline]
+ __x64_sys_write+0x93/0xd0 fs/read_write.c:652
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xcf/0x1e0 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x63/0x6b
+
+Uninit was created at:
+ __alloc_pages+0x9a6/0xe00 mm/page_alloc.c:4590
+ alloc_pages_mpol+0x62b/0x9d0 mm/mempolicy.c:2133
+ alloc_pages+0x1be/0x1e0 mm/mempolicy.c:2204
+ skb_page_frag_refill+0x2bf/0x7c0 net/core/sock.c:2909
+ tun_build_skb drivers/net/tun.c:1686 [inline]
+ tun_get_user+0xe0a/0x66e0 drivers/net/tun.c:1826
+ tun_chr_write_iter+0x3af/0x5d0 drivers/net/tun.c:2055
+ call_write_iter include/linux/fs.h:2087 [inline]
+ new_sync_write fs/read_write.c:497 [inline]
+ vfs_write+0xb6b/0x1520 fs/read_write.c:590
+ ksys_write+0x20f/0x4c0 fs/read_write.c:643
+ __do_sys_write fs/read_write.c:655 [inline]
+ __se_sys_write fs/read_write.c:652 [inline]
+ __x64_sys_write+0x93/0xd0 fs/read_write.c:652
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xcf/0x1e0 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x63/0x6b
+
+Fixes: c54419321455 ("GRE: Refactor GRE tunneling code.")
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_tunnel.c | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
+index 328f9068c6a43..3445e576b05bc 100644
+--- a/net/ipv4/ip_tunnel.c
++++ b/net/ipv4/ip_tunnel.c
+@@ -364,7 +364,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
+ bool log_ecn_error)
+ {
+ const struct iphdr *iph = ip_hdr(skb);
+- int err;
++ int nh, err;
+
+ #ifdef CONFIG_NET_IPGRE_BROADCAST
+ if (ipv4_is_multicast(iph->daddr)) {
+@@ -390,8 +390,21 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
+ tunnel->i_seqno = ntohl(tpi->seq) + 1;
+ }
+
++ /* Save offset of outer header relative to skb->head,
++ * because we are going to reset the network header to the inner header
++ * and might change skb->head.
++ */
++ nh = skb_network_header(skb) - skb->head;
++
+ skb_set_network_header(skb, (tunnel->dev->type == ARPHRD_ETHER) ? ETH_HLEN : 0);
+
++ if (!pskb_inet_may_pull(skb)) {
++ DEV_STATS_INC(tunnel->dev, rx_length_errors);
++ DEV_STATS_INC(tunnel->dev, rx_errors);
++ goto drop;
++ }
++ iph = (struct iphdr *)(skb->head + nh);
++
+ err = IP_ECN_decapsulate(iph, skb);
+ if (unlikely(err)) {
+ if (log_ecn_error)
+--
+2.43.0
+
--- /dev/null
+From 5cd90274ad2deb6ff8e810f178e8b4cc68dc740a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 14:23:50 +0000
+Subject: net: kcm: fix incorrect parameter validation in the kcm_getsockopt)
+ function
+
+From: Gavrilov Ilia <Ilia.Gavrilov@infotecs.ru>
+
+[ Upstream commit 3ed5f415133f9b7518fbe55ba9ae9a3f5e700929 ]
+
+The 'len' variable can't be negative when assigned the result of
+'min_t' because all 'min_t' parameters are cast to unsigned int,
+and then the minimum one is chosen.
+
+To fix the logic, check 'len' as read from 'optlen',
+where the types of relevant variables are (signed) int.
+
+Fixes: ab7ac4eb9832 ("kcm: Kernel Connection Multiplexor module")
+Signed-off-by: Gavrilov Ilia <Ilia.Gavrilov@infotecs.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/kcm/kcmsock.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
+index 65845c59c0655..7d37bf4334d26 100644
+--- a/net/kcm/kcmsock.c
++++ b/net/kcm/kcmsock.c
+@@ -1274,10 +1274,11 @@ static int kcm_getsockopt(struct socket *sock, int level, int optname,
+ if (get_user(len, optlen))
+ return -EFAULT;
+
+- len = min_t(unsigned int, len, sizeof(int));
+ if (len < 0)
+ return -EINVAL;
+
++ len = min_t(unsigned int, len, sizeof(int));
++
+ switch (optname) {
+ case KCM_RECV_DISABLE:
+ val = kcm->rx_disabled;
+--
+2.43.0
+
--- /dev/null
+From a4ba1fed5ddceecd0c90466705f0eea4dde603c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Feb 2024 17:51:54 +0800
+Subject: net: mctp: copy skb ext data when fragmenting
+
+From: Jeremy Kerr <jk@codeconstruct.com.au>
+
+[ Upstream commit 1394c1dec1c619a46867ed32791a29695372bff8 ]
+
+If we're fragmenting on local output, the original packet may contain
+ext data for the MCTP flows. We'll want this in the resulting fragment
+skbs too.
+
+So, do a skb_ext_copy() in the fragmentation path, and implement the
+MCTP-specific parts of an ext copy operation.
+
+Fixes: 67737c457281 ("mctp: Pass flow data & flow release events to drivers")
+Reported-by: Jian Zhang <zhangjian.3032@bytedance.com>
+Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skbuff.c | 8 ++++++++
+ net/mctp/route.c | 3 +++
+ 2 files changed, 11 insertions(+)
+
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index d4bd10f8723df..e38a4c7449f62 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -6500,6 +6500,14 @@ static struct skb_ext *skb_ext_maybe_cow(struct skb_ext *old,
+ for (i = 0; i < sp->len; i++)
+ xfrm_state_hold(sp->xvec[i]);
+ }
++#endif
++#ifdef CONFIG_MCTP_FLOWS
++ if (old_active & (1 << SKB_EXT_MCTP)) {
++ struct mctp_flow *flow = skb_ext_get_ptr(old, SKB_EXT_MCTP);
++
++ if (flow->key)
++ refcount_inc(&flow->key->refs);
++ }
+ #endif
+ __skb_ext_put(old);
+ return new;
+diff --git a/net/mctp/route.c b/net/mctp/route.c
+index 0144d8ebdaefb..05ab4fddc82e9 100644
+--- a/net/mctp/route.c
++++ b/net/mctp/route.c
+@@ -843,6 +843,9 @@ static int mctp_do_fragment_route(struct mctp_route *rt, struct sk_buff *skb,
+ /* copy message payload */
+ skb_copy_bits(skb, pos, skb_transport_header(skb2), size);
+
++ /* we need to copy the extensions, for MCTP flow data */
++ skb_ext_copy(skb2, skb);
++
+ /* do route */
+ rc = rt->output(rt, skb2);
+ if (rc)
+--
+2.43.0
+
--- /dev/null
+From b03ef7ab37ff240335f642772978622b4415ecd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 12:06:08 +0100
+Subject: net: phy: dp83822: Fix RGMII TX delay configuration
+
+From: Tim Pambor <tp@osasysteme.de>
+
+[ Upstream commit c8a5c731fd1223090af57da33838c671a7fc6a78 ]
+
+The logic for enabling the TX clock shift is inverse of enabling the RX
+clock shift. The TX clock shift is disabled when DP83822_TX_CLK_SHIFT is
+set. Correct the current behavior and always write the delay configuration
+to ensure consistent delay settings regardless of bootloader configuration.
+
+Reference: https://www.ti.com/lit/ds/symlink/dp83822i.pdf p. 69
+
+Fixes: 8095295292b5 ("net: phy: DP83822: Add setting the fixed internal delay")
+Signed-off-by: Tim Pambor <tp@osasysteme.de>
+Link: https://lore.kernel.org/r/20240305110608.104072-1-tp@osasysteme.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/dp83822.c | 37 ++++++++++++++++++++-----------------
+ 1 file changed, 20 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c
+index 267e6fd3d4448..57411ee1d8374 100644
+--- a/drivers/net/phy/dp83822.c
++++ b/drivers/net/phy/dp83822.c
+@@ -380,7 +380,7 @@ static int dp83822_config_init(struct phy_device *phydev)
+ {
+ struct dp83822_private *dp83822 = phydev->priv;
+ struct device *dev = &phydev->mdio.dev;
+- int rgmii_delay;
++ int rgmii_delay = 0;
+ s32 rx_int_delay;
+ s32 tx_int_delay;
+ int err = 0;
+@@ -390,30 +390,33 @@ static int dp83822_config_init(struct phy_device *phydev)
+ rx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
+ true);
+
+- if (rx_int_delay <= 0)
+- rgmii_delay = 0;
+- else
+- rgmii_delay = DP83822_RX_CLK_SHIFT;
++ /* Set DP83822_RX_CLK_SHIFT to enable rx clk internal delay */
++ if (rx_int_delay > 0)
++ rgmii_delay |= DP83822_RX_CLK_SHIFT;
+
+ tx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
+ false);
++
++ /* Set DP83822_TX_CLK_SHIFT to disable tx clk internal delay */
+ if (tx_int_delay <= 0)
+- rgmii_delay &= ~DP83822_TX_CLK_SHIFT;
+- else
+ rgmii_delay |= DP83822_TX_CLK_SHIFT;
+
+- if (rgmii_delay) {
+- err = phy_set_bits_mmd(phydev, DP83822_DEVADDR,
+- MII_DP83822_RCSR, rgmii_delay);
+- if (err)
+- return err;
+- }
++ err = phy_modify_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR,
++ DP83822_RX_CLK_SHIFT | DP83822_TX_CLK_SHIFT, rgmii_delay);
++ if (err)
++ return err;
++
++ err = phy_set_bits_mmd(phydev, DP83822_DEVADDR,
++ MII_DP83822_RCSR, DP83822_RGMII_MODE_EN);
+
+- phy_set_bits_mmd(phydev, DP83822_DEVADDR,
+- MII_DP83822_RCSR, DP83822_RGMII_MODE_EN);
++ if (err)
++ return err;
+ } else {
+- phy_clear_bits_mmd(phydev, DP83822_DEVADDR,
+- MII_DP83822_RCSR, DP83822_RGMII_MODE_EN);
++ err = phy_clear_bits_mmd(phydev, DP83822_DEVADDR,
++ MII_DP83822_RCSR, DP83822_RGMII_MODE_EN);
++
++ if (err)
++ return err;
+ }
+
+ if (dp83822->fx_enabled) {
+--
+2.43.0
+
--- /dev/null
+From 1abfc662602bd863a944aab27aade3959100f1ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 12:19:06 +0100
+Subject: net: phy: fix phy_get_internal_delay accessing an empty array
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kévin L'hôpital <kevin.lhopital@savoirfairelinux.com>
+
+[ Upstream commit 4469c0c5b14a0919f5965c7ceac96b523eb57b79 ]
+
+The phy_get_internal_delay function could try to access to an empty
+array in the case that the driver is calling phy_get_internal_delay
+without defining delay_values and rx-internal-delay-ps or
+tx-internal-delay-ps is defined to 0 in the device-tree.
+This will lead to "unable to handle kernel NULL pointer dereference at
+virtual address 0". To avoid this kernel oops, the test should be delay
+>= 0. As there is already delay < 0 test just before, the test could
+only be size == 0.
+
+Fixes: 92252eec913b ("net: phy: Add a helper to return the index for of the internal delay")
+Co-developed-by: Enguerrand de Ribaucourt <enguerrand.de-ribaucourt@savoirfairelinux.com>
+Signed-off-by: Enguerrand de Ribaucourt <enguerrand.de-ribaucourt@savoirfairelinux.com>
+Signed-off-by: Kévin L'hôpital <kevin.lhopital@savoirfairelinux.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/phy_device.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index 944f76e6fc8eb..45b07004669d6 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -2893,7 +2893,7 @@ s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev,
+ if (delay < 0)
+ return delay;
+
+- if (delay && size == 0)
++ if (size == 0)
+ return delay;
+
+ if (delay < delay_values[0] || delay > delay_values[size - 1]) {
+--
+2.43.0
+
--- /dev/null
+From e3ad4727f8be1aa94a496e8927b56ae8123c7e73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Oct 2023 23:58:20 +0200
+Subject: net: sunrpc: Fix an off by one in rpc_sockaddr2uaddr()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit d6f4de70f73a106986ee315d7d512539f2f3303a ]
+
+The intent is to check if the strings' are truncated or not. So, >= should
+be used instead of >, because strlcat() and snprintf() return the length of
+the output, excluding the trailing NULL.
+
+Fixes: a02d69261134 ("SUNRPC: Provide functions for managing universal addresses")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Benjamin Coddington <bcodding@redhat.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sunrpc/addr.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c
+index d435bffc61999..97ff11973c493 100644
+--- a/net/sunrpc/addr.c
++++ b/net/sunrpc/addr.c
+@@ -284,10 +284,10 @@ char *rpc_sockaddr2uaddr(const struct sockaddr *sap, gfp_t gfp_flags)
+ }
+
+ if (snprintf(portbuf, sizeof(portbuf),
+- ".%u.%u", port >> 8, port & 0xff) > (int)sizeof(portbuf))
++ ".%u.%u", port >> 8, port & 0xff) >= (int)sizeof(portbuf))
+ return NULL;
+
+- if (strlcat(addrbuf, portbuf, sizeof(addrbuf)) > sizeof(addrbuf))
++ if (strlcat(addrbuf, portbuf, sizeof(addrbuf)) >= sizeof(addrbuf))
+ return NULL;
+
+ return kstrdup(addrbuf, gfp_flags);
+--
+2.43.0
+
--- /dev/null
+From 243ebcaae4ee1d075b0e0c8601fb0c235d0082a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 14:23:50 +0000
+Subject: net/x25: fix incorrect parameter validation in the x25_getsockopt()
+ function
+
+From: Gavrilov Ilia <Ilia.Gavrilov@infotecs.ru>
+
+[ Upstream commit d6eb8de2015f0c24822e47356f839167ebde2945 ]
+
+The 'len' variable can't be negative when assigned the result of
+'min_t' because all 'min_t' parameters are cast to unsigned int,
+and then the minimum one is chosen.
+
+To fix the logic, check 'len' as read from 'optlen',
+where the types of relevant variables are (signed) int.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Gavrilov Ilia <Ilia.Gavrilov@infotecs.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/x25/af_x25.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
+index 5c7ad301d742e..5a8b2ea56564e 100644
+--- a/net/x25/af_x25.c
++++ b/net/x25/af_x25.c
+@@ -460,12 +460,12 @@ static int x25_getsockopt(struct socket *sock, int level, int optname,
+ if (get_user(len, optlen))
+ goto out;
+
+- len = min_t(unsigned int, len, sizeof(int));
+-
+ rc = -EINVAL;
+ if (len < 0)
+ goto out;
+
++ len = min_t(unsigned int, len, sizeof(int));
++
+ rc = -EFAULT;
+ if (put_user(len, optlen))
+ goto out;
+--
+2.43.0
+
--- /dev/null
+From d52c5d5b8f4c4535ea93748beee9dc8e23b1a630 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Mar 2024 22:25:40 +0800
+Subject: nfp: flower: handle acti_netdevs allocation failure
+
+From: Duoming Zhou <duoming@zju.edu.cn>
+
+[ Upstream commit 84e95149bd341705f0eca6a7fcb955c548805002 ]
+
+The kmalloc_array() in nfp_fl_lag_do_work() will return null, if
+the physical memory has run out. As a result, if we dereference
+the acti_netdevs, the null pointer dereference bugs will happen.
+
+This patch adds a check to judge whether allocation failure occurs.
+If it happens, the delayed work will be rescheduled and try again.
+
+Fixes: bb9a8d031140 ("nfp: flower: monitor and offload LAG groups")
+Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
+Reviewed-by: Louis Peens <louis.peens@corigine.com>
+Link: https://lore.kernel.org/r/20240308142540.9674-1-duoming@zju.edu.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/netronome/nfp/flower/lag_conf.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/netronome/nfp/flower/lag_conf.c b/drivers/net/ethernet/netronome/nfp/flower/lag_conf.c
+index e92860e20a24a..c6a2c302a8c8b 100644
+--- a/drivers/net/ethernet/netronome/nfp/flower/lag_conf.c
++++ b/drivers/net/ethernet/netronome/nfp/flower/lag_conf.c
+@@ -308,6 +308,11 @@ static void nfp_fl_lag_do_work(struct work_struct *work)
+
+ acti_netdevs = kmalloc_array(entry->slave_cnt,
+ sizeof(*acti_netdevs), GFP_KERNEL);
++ if (!acti_netdevs) {
++ schedule_delayed_work(&lag->work,
++ NFP_FL_LAG_DELAY);
++ continue;
++ }
+
+ /* Include sanity check in the loop. It may be that a bond has
+ * changed between processing the last notification and the
+--
+2.43.0
+
--- /dev/null
+From 0058e6be38035d75821158e454b58182d391f6ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Feb 2024 22:16:53 +0100
+Subject: NFS: Fix an off by one in root_nfs_cat()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 698ad1a538da0b6bf969cfee630b4e3a026afb87 ]
+
+The intent is to check if 'dest' is truncated or not. So, >= should be
+used instead of >, because strlcat() returns the length of 'dest' and 'src'
+excluding the trailing NULL.
+
+Fixes: 56463e50d1fc ("NFS: Use super.c for NFSROOT mount option parsing")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Benjamin Coddington <bcodding@redhat.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfsroot.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
+index 620329b7e6aeb..0b1c1d2e076c1 100644
+--- a/fs/nfs/nfsroot.c
++++ b/fs/nfs/nfsroot.c
+@@ -175,10 +175,10 @@ static int __init root_nfs_cat(char *dest, const char *src,
+ size_t len = strlen(dest);
+
+ if (len && dest[len - 1] != ',')
+- if (strlcat(dest, ",", destlen) > destlen)
++ if (strlcat(dest, ",", destlen) >= destlen)
+ return -1;
+
+- if (strlcat(dest, src, destlen) > destlen)
++ if (strlcat(dest, src, destlen) >= destlen)
+ return -1;
+ return 0;
+ }
+--
+2.43.0
+
--- /dev/null
+From fc0e450faa15b2731573c77e888ebc505cffce4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Mar 2024 11:11:53 -0400
+Subject: nfs: fix panic when nfs4_ff_layout_prepare_ds() fails
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit 719fcafe07c12646691bd62d7f8d94d657fa0766 ]
+
+We've been seeing the following panic in production
+
+BUG: kernel NULL pointer dereference, address: 0000000000000065
+PGD 2f485f067 P4D 2f485f067 PUD 2cc5d8067 PMD 0
+RIP: 0010:ff_layout_cancel_io+0x3a/0x90 [nfs_layout_flexfiles]
+Call Trace:
+ <TASK>
+ ? __die+0x78/0xc0
+ ? page_fault_oops+0x286/0x380
+ ? __rpc_execute+0x2c3/0x470 [sunrpc]
+ ? rpc_new_task+0x42/0x1c0 [sunrpc]
+ ? exc_page_fault+0x5d/0x110
+ ? asm_exc_page_fault+0x22/0x30
+ ? ff_layout_free_layoutreturn+0x110/0x110 [nfs_layout_flexfiles]
+ ? ff_layout_cancel_io+0x3a/0x90 [nfs_layout_flexfiles]
+ ? ff_layout_cancel_io+0x6f/0x90 [nfs_layout_flexfiles]
+ pnfs_mark_matching_lsegs_return+0x1b0/0x360 [nfsv4]
+ pnfs_error_mark_layout_for_return+0x9e/0x110 [nfsv4]
+ ? ff_layout_send_layouterror+0x50/0x160 [nfs_layout_flexfiles]
+ nfs4_ff_layout_prepare_ds+0x11f/0x290 [nfs_layout_flexfiles]
+ ff_layout_pg_init_write+0xf0/0x1f0 [nfs_layout_flexfiles]
+ __nfs_pageio_add_request+0x154/0x6c0 [nfs]
+ nfs_pageio_add_request+0x26b/0x380 [nfs]
+ nfs_do_writepage+0x111/0x1e0 [nfs]
+ nfs_writepages_callback+0xf/0x30 [nfs]
+ write_cache_pages+0x17f/0x380
+ ? nfs_pageio_init_write+0x50/0x50 [nfs]
+ ? nfs_writepages+0x6d/0x210 [nfs]
+ ? nfs_writepages+0x6d/0x210 [nfs]
+ nfs_writepages+0x125/0x210 [nfs]
+ do_writepages+0x67/0x220
+ ? generic_perform_write+0x14b/0x210
+ filemap_fdatawrite_wbc+0x5b/0x80
+ file_write_and_wait_range+0x6d/0xc0
+ nfs_file_fsync+0x81/0x170 [nfs]
+ ? nfs_file_mmap+0x60/0x60 [nfs]
+ __x64_sys_fsync+0x53/0x90
+ do_syscall_64+0x3d/0x90
+ entry_SYSCALL_64_after_hwframe+0x46/0xb0
+
+Inspecting the core with drgn I was able to pull this
+
+ >>> prog.crashed_thread().stack_trace()[0]
+ #0 at 0xffffffffa079657a (ff_layout_cancel_io+0x3a/0x84) in ff_layout_cancel_io at fs/nfs/flexfilelayout/flexfilelayout.c:2021:27
+ >>> prog.crashed_thread().stack_trace()[0]['idx']
+ (u32)1
+ >>> prog.crashed_thread().stack_trace()[0]['flseg'].mirror_array[1].mirror_ds
+ (struct nfs4_ff_layout_ds *)0xffffffffffffffed
+
+This is clear from the stack trace, we call nfs4_ff_layout_prepare_ds()
+which could error out initializing the mirror_ds, and then we go to
+clean it all up and our check is only for if (!mirror->mirror_ds). This
+is inconsistent with the rest of the users of mirror_ds, which have
+
+ if (IS_ERR_OR_NULL(mirror_ds))
+
+to keep from tripping over this exact scenario. Fix this up in
+ff_layout_cancel_io() to make sure we don't panic when we get an error.
+I also spot checked all the other instances of checking mirror_ds and we
+appear to be doing the correct checks everywhere, only unconditionally
+dereferencing mirror_ds when we know it would be valid.
+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Fixes: b739a5bd9d9f ("NFSv4/flexfiles: Cancel I/O if the layout is recalled or revoked")
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/flexfilelayout/flexfilelayout.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
+index 81bbafab18a99..4376881be7918 100644
+--- a/fs/nfs/flexfilelayout/flexfilelayout.c
++++ b/fs/nfs/flexfilelayout/flexfilelayout.c
+@@ -2016,7 +2016,7 @@ static void ff_layout_cancel_io(struct pnfs_layout_segment *lseg)
+ for (idx = 0; idx < flseg->mirror_array_cnt; idx++) {
+ mirror = flseg->mirror_array[idx];
+ mirror_ds = mirror->mirror_ds;
+- if (!mirror_ds)
++ if (IS_ERR_OR_NULL(mirror_ds))
+ continue;
+ ds = mirror->mirror_ds->ds;
+ if (!ds)
+--
+2.43.0
+
--- /dev/null
+From 7acca7f9df56a8f90639e8f033a90735cb8d21ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Jan 2024 07:51:28 -0700
+Subject: NFSv4.2: fix listxattr maximum XDR buffer size
+
+From: Jorge Mora <jmora1300@gmail.com>
+
+[ Upstream commit bcac8bff90a6ee1629f90669cdb9d28fb86049b0 ]
+
+Switch order of operations to avoid creating a short XDR buffer:
+e.g., buflen = 12, old xdrlen = 12, new xdrlen = 20.
+
+Having a short XDR buffer leads to lxa_maxcount be a few bytes
+less than what is needed to retrieve the whole list when using
+a buflen as returned by a call with size = 0:
+ buflen = listxattr(path, NULL, 0);
+ buf = malloc(buflen);
+ buflen = listxattr(path, buf, buflen);
+
+For a file with one attribute (name = '123456'), the first call
+with size = 0 will return buflen = 12 ('user.123456\x00').
+The second call with size = 12, sends LISTXATTRS with
+lxa_maxcount = 12 + 8 (cookie) + 4 (array count) = 24. The
+XDR buffer needs 8 (cookie) + 4 (array count) + 4 (name count)
++ 6 (name len) + 2 (padding) + 4 (eof) = 28 which is 4 bytes
+shorter than the lxa_maxcount provided in the call.
+
+Fixes: 04a5da690e8f ("NFSv4.2: define limits and sizes for user xattr handling")
+Signed-off-by: Jorge Mora <mora@netapp.com>
+Reviewed-by: Benjamin Coddington <bcodding@redhat.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs42.h | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/fs/nfs/nfs42.h b/fs/nfs/nfs42.h
+index b59876b01a1e3..0282d93c8bccb 100644
+--- a/fs/nfs/nfs42.h
++++ b/fs/nfs/nfs42.h
+@@ -55,11 +55,14 @@ int nfs42_proc_removexattr(struct inode *inode, const char *name);
+ * They would be 7 bytes long in the eventual buffer ("user.x\0"), and
+ * 8 bytes long XDR-encoded.
+ *
+- * Include the trailing eof word as well.
++ * Include the trailing eof word as well and make the result a multiple
++ * of 4 bytes.
+ */
+ static inline u32 nfs42_listxattr_xdrsize(u32 buflen)
+ {
+- return ((buflen / (XATTR_USER_PREFIX_LEN + 2)) * 8) + 4;
++ u32 size = 8 * buflen / (XATTR_USER_PREFIX_LEN + 2) + 4;
++
++ return (size + 3) & ~3;
+ }
+ #endif /* CONFIG_NFS_V4_2 */
+ #endif /* __LINUX_FS_NFS_NFS4_2_H */
+--
+2.43.0
+
--- /dev/null
+From 55d25d926c88b0bbd3526989b14644a670769c54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Jan 2024 07:56:12 -0700
+Subject: NFSv4.2: fix nfs4_listxattr kernel BUG at mm/usercopy.c:102
+
+From: Jorge Mora <jmora1300@gmail.com>
+
+[ Upstream commit 251a658bbfceafb4d58c76b77682c8bf7bcfad65 ]
+
+A call to listxattr() with a buffer size = 0 returns the actual
+size of the buffer needed for a subsequent call. When size > 0,
+nfs4_listxattr() does not return an error because either
+generic_listxattr() or nfs4_listxattr_nfs4_label() consumes
+exactly all the bytes then size is 0 when calling
+nfs4_listxattr_nfs4_user() which then triggers the following
+kernel BUG:
+
+ [ 99.403778] kernel BUG at mm/usercopy.c:102!
+ [ 99.404063] Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
+ [ 99.408463] CPU: 0 PID: 3310 Comm: python3 Not tainted 6.6.0-61.fc40.aarch64 #1
+ [ 99.415827] Call trace:
+ [ 99.415985] usercopy_abort+0x70/0xa0
+ [ 99.416227] __check_heap_object+0x134/0x158
+ [ 99.416505] check_heap_object+0x150/0x188
+ [ 99.416696] __check_object_size.part.0+0x78/0x168
+ [ 99.416886] __check_object_size+0x28/0x40
+ [ 99.417078] listxattr+0x8c/0x120
+ [ 99.417252] path_listxattr+0x78/0xe0
+ [ 99.417476] __arm64_sys_listxattr+0x28/0x40
+ [ 99.417723] invoke_syscall+0x78/0x100
+ [ 99.417929] el0_svc_common.constprop.0+0x48/0xf0
+ [ 99.418186] do_el0_svc+0x24/0x38
+ [ 99.418376] el0_svc+0x3c/0x110
+ [ 99.418554] el0t_64_sync_handler+0x120/0x130
+ [ 99.418788] el0t_64_sync+0x194/0x198
+ [ 99.418994] Code: aa0003e3 d000a3e0 91310000 97f49bdb (d4210000)
+
+Issue is reproduced when generic_listxattr() returns 'system.nfs4_acl',
+thus calling lisxattr() with size = 16 will trigger the bug.
+
+Add check on nfs4_listxattr() to return ERANGE error when it is
+called with size > 0 and the return value is greater than size.
+
+Fixes: 012a211abd5d ("NFSv4.2: hook in the user extended attribute handlers")
+Signed-off-by: Jorge Mora <mora@netapp.com>
+Reviewed-by: Benjamin Coddington <bcodding@redhat.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/nfs4proc.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index ec3f0103e1a7f..7cc74f7451d67 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -10592,29 +10592,33 @@ const struct nfs4_minor_version_ops *nfs_v4_minor_ops[] = {
+ static ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size)
+ {
+ ssize_t error, error2, error3;
++ size_t left = size;
+
+- error = generic_listxattr(dentry, list, size);
++ error = generic_listxattr(dentry, list, left);
+ if (error < 0)
+ return error;
+ if (list) {
+ list += error;
+- size -= error;
++ left -= error;
+ }
+
+- error2 = nfs4_listxattr_nfs4_label(d_inode(dentry), list, size);
++ error2 = nfs4_listxattr_nfs4_label(d_inode(dentry), list, left);
+ if (error2 < 0)
+ return error2;
+
+ if (list) {
+ list += error2;
+- size -= error2;
++ left -= error2;
+ }
+
+- error3 = nfs4_listxattr_nfs4_user(d_inode(dentry), list, size);
++ error3 = nfs4_listxattr_nfs4_user(d_inode(dentry), list, left);
+ if (error3 < 0)
+ return error3;
+
+- return error + error2 + error3;
++ error += error2 + error3;
++ if (size && error > size)
++ return -ERANGE;
++ return error;
+ }
+
+ static void nfs4_enable_swap(struct inode *inode)
+--
+2.43.0
+
--- /dev/null
+From e8af566d07bc6e61a79020e4f08f46d902683624 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Nov 2022 17:28:52 +0800
+Subject: NTB: EPF: fix possible memory leak in pci_vntb_probe()
+
+From: ruanjinjie <ruanjinjie@huawei.com>
+
+[ Upstream commit 956578e3d397e00d6254dc7b5194d28587f98518 ]
+
+As ntb_register_device() don't handle error of device_register(),
+if ntb_register_device() returns error in pci_vntb_probe(), name of kobject
+which is allocated in dev_set_name() called in device_add() is leaked.
+
+As comment of device_add() says, it should call put_device() to drop the
+reference count that was set in device_initialize()
+when it fails, so the name can be freed in kobject_cleanup().
+
+Signed-off-by: ruanjinjie <ruanjinjie@huawei.com>
+Signed-off-by: Jon Mason <jdmason@kudzu.us>
+Stable-dep-of: aebfdfe39b93 ("NTB: fix possible name leak in ntb_register_device()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/pci-epf-vntb.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
+index 8c6931210ac4d..cd985a41c8d65 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
++++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
+@@ -1288,6 +1288,7 @@ static int pci_vntb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ return 0;
+
+ err_register_dev:
++ put_device(&ndev->ntb.dev);
+ return -EINVAL;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From be7bc393e0a13910232a0ca8fa01379ac90735f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Dec 2023 11:30:56 +0800
+Subject: NTB: fix possible name leak in ntb_register_device()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit aebfdfe39b9327a3077d0df8db3beb3160c9bdd0 ]
+
+If device_register() fails in ntb_register_device(), the device name
+allocated by dev_set_name() should be freed. As per the comment in
+device_register(), callers should use put_device() to give up the
+reference in the error path. So fix this by calling put_device() in the
+error path so that the name can be freed in kobject_cleanup().
+
+As a result of this, put_device() in the error path of
+ntb_register_device() is removed and the actual error is returned.
+
+Fixes: a1bd3baeb2f1 ("NTB: Add NTB hardware abstraction layer")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/20231201033057.1399131-1-yangyingliang@huaweicloud.com
+[mani: reworded commit message]
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ntb/core.c | 8 +++++++-
+ drivers/pci/endpoint/functions/pci-epf-vntb.c | 6 +-----
+ 2 files changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/ntb/core.c b/drivers/ntb/core.c
+index 27dd93deff6e5..d702bee780826 100644
+--- a/drivers/ntb/core.c
++++ b/drivers/ntb/core.c
+@@ -100,6 +100,8 @@ EXPORT_SYMBOL(ntb_unregister_client);
+
+ int ntb_register_device(struct ntb_dev *ntb)
+ {
++ int ret;
++
+ if (!ntb)
+ return -EINVAL;
+ if (!ntb->pdev)
+@@ -120,7 +122,11 @@ int ntb_register_device(struct ntb_dev *ntb)
+ ntb->ctx_ops = NULL;
+ spin_lock_init(&ntb->ctx_lock);
+
+- return device_register(&ntb->dev);
++ ret = device_register(&ntb->dev);
++ if (ret)
++ put_device(&ntb->dev);
++
++ return ret;
+ }
+ EXPORT_SYMBOL(ntb_register_device);
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
+index cd985a41c8d65..b4c1a4f6029d4 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
++++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
+@@ -1281,15 +1281,11 @@ static int pci_vntb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ ret = ntb_register_device(&ndev->ntb);
+ if (ret) {
+ dev_err(dev, "Failed to register NTB device\n");
+- goto err_register_dev;
++ return ret;
+ }
+
+ dev_dbg(dev, "PCI Virtual NTB driver loaded\n");
+ return 0;
+-
+-err_register_dev:
+- put_device(&ndev->ntb.dev);
+- return -EINVAL;
+ }
+
+ static struct pci_device_id pci_vntb_table[] = {
+--
+2.43.0
+
--- /dev/null
+From 476a7eaf105a46d6a7fa9a0757e09c2efa59a2e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Mar 2024 16:48:28 +0530
+Subject: OPP: debugfs: Fix warning around icc_get_name()
+
+From: Viresh Kumar <viresh.kumar@linaro.org>
+
+[ Upstream commit 28330ceb953e39880ea77da4895bb902a1244860 ]
+
+If the kernel isn't built with interconnect support, icc_get_name()
+returns NULL and we get following warning:
+
+drivers/opp/debugfs.c: In function 'bw_name_read':
+drivers/opp/debugfs.c:43:42: error: '%.62s' directive argument is null [-Werror=format-overflow=]
+ i = scnprintf(buf, sizeof(buf), "%.62s\n", icc_get_name(path));
+
+Fix it.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202402141313.81ltVF5g-lkp@intel.com/
+Fixes: 0430b1d5704b0 ("opp: Expose bandwidth information via debugfs")
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Reviewed-by: Dhruva Gole <d-gole@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/opp/debugfs.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/opp/debugfs.c b/drivers/opp/debugfs.c
+index 2c7fb683441ef..de81bbf4be100 100644
+--- a/drivers/opp/debugfs.c
++++ b/drivers/opp/debugfs.c
+@@ -37,10 +37,12 @@ static ssize_t bw_name_read(struct file *fp, char __user *userbuf,
+ size_t count, loff_t *ppos)
+ {
+ struct icc_path *path = fp->private_data;
++ const char *name = icc_get_name(path);
+ char buf[64];
+- int i;
++ int i = 0;
+
+- i = scnprintf(buf, sizeof(buf), "%.62s\n", icc_get_name(path));
++ if (name)
++ i = scnprintf(buf, sizeof(buf), "%.62s\n", name);
+
+ return simple_read_from_buffer(userbuf, count, ppos, buf, i);
+ }
+--
+2.43.0
+
--- /dev/null
+From 03d7f19ce5524ff6fd2d72fbf32e04da2692ea6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Feb 2024 14:16:34 +0100
+Subject: PCI/AER: Fix rootport attribute paths in ABI docs
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+[ Upstream commit 0e7d29a39a546161ea3a49e8e282a43212d7ff68 ]
+
+The 'aer_stats' directory never made it into the sixth and final revision
+of the series adding the sysfs AER attributes.
+
+Link: https://lore.kernel.org/r/20240202131635.11405-2-johan+linaro@kernel.org
+Link: https://lore.kernel.org/lkml/20180621184822.GB14136@bhelgaas-glaptop.roam.corp.google.com/
+Fixes: 12833017e581 ("PCI/AER: Add sysfs attributes for rootport cumulative stats")
+Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats b/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats
+index 860db53037a58..24087d5fd417a 100644
+--- a/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats
++++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-aer_stats
+@@ -100,19 +100,19 @@ collectors) that are AER capable. These indicate the number of error messages as
+ device, so these counters include them and are thus cumulative of all the error
+ messages on the PCI hierarchy originating at that root port.
+
+-What: /sys/bus/pci/devices/<dev>/aer_stats/aer_rootport_total_err_cor
++What: /sys/bus/pci/devices/<dev>/aer_rootport_total_err_cor
+ Date: July 2018
+ KernelVersion: 4.19.0
+ Contact: linux-pci@vger.kernel.org, rajatja@google.com
+ Description: Total number of ERR_COR messages reported to rootport.
+
+-What: /sys/bus/pci/devices/<dev>/aer_stats/aer_rootport_total_err_fatal
++What: /sys/bus/pci/devices/<dev>/aer_rootport_total_err_fatal
+ Date: July 2018
+ KernelVersion: 4.19.0
+ Contact: linux-pci@vger.kernel.org, rajatja@google.com
+ Description: Total number of ERR_FATAL messages reported to rootport.
+
+-What: /sys/bus/pci/devices/<dev>/aer_stats/aer_rootport_total_err_nonfatal
++What: /sys/bus/pci/devices/<dev>/aer_rootport_total_err_nonfatal
+ Date: July 2018
+ KernelVersion: 4.19.0
+ Contact: linux-pci@vger.kernel.org, rajatja@google.com
+--
+2.43.0
+
--- /dev/null
+From f0d19e64f05c6d5ffe6716895749752207eb57b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Jan 2024 13:08:15 +0200
+Subject: PCI/DPC: Print all TLP Prefixes, not just the first
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 6568d82512b0a64809acff3d7a747362fa4288c8 ]
+
+The TLP Prefix Log Register consists of multiple DWORDs (PCIe r6.1 sec
+7.9.14.13) but the loop in dpc_process_rp_pio_error() keeps reading from
+the first DWORD, so we print only the first PIO TLP Prefix (duplicated
+several times), and we never print the second, third, etc., Prefixes.
+
+Add the iteration count based offset calculation into the config read.
+
+Fixes: f20c4ea49ec4 ("PCI/DPC: Add eDPC support")
+Link: https://lore.kernel.org/r/20240118110815.3867-1-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+[bhelgaas: add user-visible details to commit log]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pcie/dpc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
+index a5d7c69b764e0..08800282825e1 100644
+--- a/drivers/pci/pcie/dpc.c
++++ b/drivers/pci/pcie/dpc.c
+@@ -231,7 +231,7 @@ static void dpc_process_rp_pio_error(struct pci_dev *pdev)
+
+ for (i = 0; i < pdev->dpc_rp_log_size - 5; i++) {
+ pci_read_config_dword(pdev,
+- cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG, &prefix);
++ cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG + i * 4, &prefix);
+ pci_err(pdev, "TLP Prefix Header: dw%d, %#010x\n", i, prefix);
+ }
+ clear_status:
+--
+2.43.0
+
--- /dev/null
+From 67dedcdfa68c2e44beee79f442be3a9bccd581a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 20:21:14 +0800
+Subject: PCI: Make pci_dev_is_disconnected() helper public for other drivers
+
+From: Ethan Zhao <haifeng.zhao@linux.intel.com>
+
+[ Upstream commit 39714fd73c6b60a8d27bcc5b431afb0828bf4434 ]
+
+Make pci_dev_is_disconnected() public so that it can be called from
+Intel VT-d driver to quickly fix/workaround the surprise removal
+unplug hang issue for those ATS capable devices on PCIe switch downstream
+hotplug capable ports.
+
+Beside pci_device_is_present() function, this one has no config space
+space access, so is light enough to optimize the normal pure surprise
+removal and safe removal flow.
+
+Acked-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
+Tested-by: Haorong Ye <yehaorong@bytedance.com>
+Signed-off-by: Ethan Zhao <haifeng.zhao@linux.intel.com>
+Link: https://lore.kernel.org/r/20240301080727.3529832-2-haifeng.zhao@linux.intel.com
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Stable-dep-of: 4fc82cd907ac ("iommu/vt-d: Don't issue ATS Invalidation request when device is disconnected")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci.h | 5 -----
+ include/linux/pci.h | 5 +++++
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
+index e1d02b7c60294..9950deeb047a7 100644
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -357,11 +357,6 @@ static inline int pci_dev_set_disconnected(struct pci_dev *dev, void *unused)
+ return 0;
+ }
+
+-static inline bool pci_dev_is_disconnected(const struct pci_dev *dev)
+-{
+- return dev->error_state == pci_channel_io_perm_failure;
+-}
+-
+ /* pci_dev priv_flags */
+ #define PCI_DEV_ADDED 0
+ #define PCI_DPC_RECOVERED 1
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+index eccaf1abea79d..f5d89a4b811f1 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -2355,6 +2355,11 @@ static inline struct pci_dev *pcie_find_root_port(struct pci_dev *dev)
+ return NULL;
+ }
+
++static inline bool pci_dev_is_disconnected(const struct pci_dev *dev)
++{
++ return dev->error_state == pci_channel_io_perm_failure;
++}
++
+ void pci_request_acs(void);
+ bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags);
+ bool pci_acs_path_enabled(struct pci_dev *start,
+--
+2.43.0
+
--- /dev/null
+From 9b81241c0f86f27e0ff05304a62545155b6ed26a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Feb 2024 14:28:11 +0100
+Subject: PCI: Mark 3ware-9650SE Root Port Extended Tags as broken
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jörg Wedekind <joerg@wedekind.de>
+
+[ Upstream commit baf67aefbe7d7deafa59ca49612d163f8889934c ]
+
+Per PCIe r6.1, sec 2.2.6.2 and 7.5.3.4, a Requester may not use 8-bit Tags
+unless its Extended Tag Field Enable is set, but all Receivers/Completers
+must handle 8-bit Tags correctly regardless of their Extended Tag Field
+Enable.
+
+Some devices do not handle 8-bit Tags as Completers, so add a quirk for
+them. If we find such a device, we disable Extended Tags for the entire
+hierarchy to make peer-to-peer DMA possible.
+
+The 3ware 9650SE seems to have issues with handling 8-bit tags. Mark it as
+broken.
+
+This fixes PCI Parity Errors like :
+
+ 3w-9xxx: scsi0: ERROR: (0x06:0x000C): PCI Parity Error: clearing.
+ 3w-9xxx: scsi0: ERROR: (0x06:0x000D): PCI Abort: clearing.
+ 3w-9xxx: scsi0: ERROR: (0x06:0x000E): Controller Queue Error: clearing.
+ 3w-9xxx: scsi0: ERROR: (0x06:0x0010): Microcontroller Error: clearing.
+
+Link: https://lore.kernel.org/r/20240219132811.8351-1-joerg@wedekind.de
+Fixes: 60db3a4d8cc9 ("PCI: Enable PCIe Extended Tags if supported")
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=202425
+Signed-off-by: Jörg Wedekind <joerg@wedekind.de>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/quirks.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+index 51d634fbdfb8e..c175b70a984c6 100644
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -5415,6 +5415,7 @@ static void quirk_no_ext_tags(struct pci_dev *pdev)
+
+ pci_walk_bus(bridge->bus, pci_configure_extended_tags, NULL);
+ }
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_3WARE, 0x1004, quirk_no_ext_tags);
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0132, quirk_no_ext_tags);
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0140, quirk_no_ext_tags);
+ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0141, quirk_no_ext_tags);
+--
+2.43.0
+
--- /dev/null
+From 44325f1cb9aa0247083df08cb5dd0567ec08cb47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Dec 2023 15:30:01 +0100
+Subject: PCI: switchtec: Fix an error handling path in switchtec_pci_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit dec529b0b0572b32f9eb91c882dd1f08ca657efb ]
+
+The commit in Fixes changed the logic on how resources are released and
+introduced a new switchtec_exit_pci() that need to be called explicitly in
+order to undo a corresponding switchtec_init_pci().
+
+This was done in the remove function, but not in the probe.
+
+Fix the probe now.
+
+Fixes: df25461119d9 ("PCI: switchtec: Fix stdev_release() crash after surprise hot remove")
+Link: https://lore.kernel.org/r/01446d2ccb91a578239915812f2b7dfbeb2882af.1703428183.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/switch/switchtec.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
+index 3f3320d0a4f8f..d05a482639e3c 100644
+--- a/drivers/pci/switch/switchtec.c
++++ b/drivers/pci/switch/switchtec.c
+@@ -1674,7 +1674,7 @@ static int switchtec_pci_probe(struct pci_dev *pdev,
+ rc = switchtec_init_isr(stdev);
+ if (rc) {
+ dev_err(&stdev->dev, "failed to init isr.\n");
+- goto err_put;
++ goto err_exit_pci;
+ }
+
+ iowrite32(SWITCHTEC_EVENT_CLEAR |
+@@ -1695,6 +1695,8 @@ static int switchtec_pci_probe(struct pci_dev *pdev,
+
+ err_devadd:
+ stdev_kill(stdev);
++err_exit_pci:
++ switchtec_exit_pci(stdev);
+ err_put:
+ ida_free(&switchtec_minor_ida, MINOR(stdev->dev.devt));
+ put_device(&stdev->dev);
+--
+2.43.0
+
--- /dev/null
+From 8a34809719766326461ae80f3e72421a06036c8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 27 Jan 2024 02:57:56 +0000
+Subject: perf evsel: Fix duplicate initialization of data->id in
+ evsel__parse_sample()
+
+From: Yang Jihong <yangjihong1@huawei.com>
+
+[ Upstream commit 4962aec0d684c8edb14574ccd0da53e4926ff834 ]
+
+data->id has been initialized at line 2362, remove duplicate initialization.
+
+Fixes: 3ad31d8a0df2 ("perf evsel: Centralize perf_sample initialization")
+Signed-off-by: Yang Jihong <yangjihong1@huawei.com>
+Reviewed-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Reviewed-by: Ian Rogers <irogers@google.com>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/r/20240127025756.4041808-1-yangjihong1@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/evsel.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
+index 76605fde35078..7db35dbdfcefe 100644
+--- a/tools/perf/util/evsel.c
++++ b/tools/perf/util/evsel.c
+@@ -2375,7 +2375,6 @@ int evsel__parse_sample(struct evsel *evsel, union perf_event *event,
+ data->period = evsel->core.attr.sample_period;
+ data->cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+ data->misc = event->header.misc;
+- data->id = -1ULL;
+ data->data_src = PERF_MEM_DATA_SRC_NONE;
+ data->vcpu = -1;
+
+--
+2.43.0
+
--- /dev/null
+From edc6ca332cbcef3d462eefc3a265df0b8c3c240e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jan 2024 04:03:02 +0000
+Subject: perf record: Fix possible incorrect free in record__switch_output()
+
+From: Yang Jihong <yangjihong1@huawei.com>
+
+[ Upstream commit aff10a165201f6f60cff225083ce301ad3f5d8f1 ]
+
+perf_data__switch() may not assign a legal value to 'new_filename'.
+In this case, 'new_filename' uses the on-stack value, which may cause a
+incorrect free and unexpected result.
+
+Fixes: 03724b2e9c45 ("perf record: Allow to limit number of reported perf.data files")
+Signed-off-by: Yang Jihong <yangjihong1@huawei.com>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/r/20240119040304.3708522-2-yangjihong1@huawei.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-record.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
+index 7314183cdcb6c..b9b0fda8374e2 100644
+--- a/tools/perf/builtin-record.c
++++ b/tools/perf/builtin-record.c
+@@ -1785,8 +1785,8 @@ static int
+ record__switch_output(struct record *rec, bool at_exit)
+ {
+ struct perf_data *data = &rec->data;
++ char *new_filename = NULL;
+ int fd, err;
+- char *new_filename;
+
+ /* Same Size: "2015122520103046"*/
+ char timestamp[] = "InvalidTimestamp";
+--
+2.43.0
+
--- /dev/null
+From 8de29f4662d7fd7805e9452f5b7be641b3a9e604 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Feb 2024 12:49:46 -0800
+Subject: perf stat: Avoid metric-only segv
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 2543947c77e0e224bda86b4e7220c2f6714da463 ]
+
+Cycles is recognized as part of a hard coded metric in stat-shadow.c,
+it may call print_metric_only with a NULL fmt string leading to a
+segfault. Handle the NULL fmt explicitly.
+
+Fixes: 088519f318be ("perf stat: Move the display functions to stat-display.c")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
+Cc: K Prateek Nayak <kprateek.nayak@amd.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Kaige Ye <ye@kaige.org>
+Cc: John Garry <john.g.garry@oracle.com>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/r/20240209204947.3873294-4-irogers@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/stat-display.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
+index bc866d18973e4..ef9a3df459657 100644
+--- a/tools/perf/util/stat-display.c
++++ b/tools/perf/util/stat-display.c
+@@ -366,7 +366,7 @@ static void print_metric_only(struct perf_stat_config *config,
+ if (color)
+ mlen += strlen(color) + sizeof(PERF_COLOR_RESET) - 1;
+
+- color_snprintf(str, sizeof(str), color ?: "", fmt, val);
++ color_snprintf(str, sizeof(str), color ?: "", fmt ?: "", val);
+ fprintf(out, "%*s ", mlen, str);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 1bc1699f1761c7b11000d7c2f74536aab55d7361 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Feb 2024 08:32:28 +0000
+Subject: perf thread_map: Free strlist on normal path in
+ thread_map__new_by_tid_str()
+
+From: Yang Jihong <yangjihong1@huawei.com>
+
+[ Upstream commit 1eb3d924e3c0b8c27388b0583a989d757866efb6 ]
+
+slist needs to be freed in both error path and normal path in
+thread_map__new_by_tid_str().
+
+Fixes: b52956c961be3a04 ("perf tools: Allow multiple threads or processes in record, stat, top")
+Reviewed-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Yang Jihong <yangjihong1@huawei.com>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/r/20240206083228.172607-6-yangjihong1@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/thread_map.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
+index c9bfe4696943b..cee7fc3b5bb0c 100644
+--- a/tools/perf/util/thread_map.c
++++ b/tools/perf/util/thread_map.c
+@@ -279,13 +279,13 @@ struct perf_thread_map *thread_map__new_by_tid_str(const char *tid_str)
+ threads->nr = ntasks;
+ }
+ out:
++ strlist__delete(slist);
+ if (threads)
+ refcount_set(&threads->refcnt, 1);
+ return threads;
+
+ out_free_threads:
+ zfree(&threads);
+- strlist__delete(slist);
+ goto out;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 736ea21067dccb5cdeed7a2433cc8fbafcf04654 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Jan 2024 16:36:26 +0530
+Subject: perf/x86/amd/core: Avoid register reset when CPU is dead
+
+From: Sandipan Das <sandipan.das@amd.com>
+
+[ Upstream commit ad8c91282c95f801c37812d59d2d9eba6899b384 ]
+
+When bringing a CPU online, some of the PMC and LBR related registers
+are reset. The same is done when a CPU is taken offline although that
+is unnecessary. This currently happens in the "cpu_dead" callback which
+is also incorrect as the callback runs on a control CPU instead of the
+one that is being taken offline. This also affects hibernation and
+suspend to RAM on some platforms as reported in the link below.
+
+Fixes: 21d59e3e2c40 ("perf/x86/amd/core: Detect PerfMonV2 support")
+Reported-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Sandipan Das <sandipan.das@amd.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/550a026764342cf7e5812680e3e2b91fe662b5ac.1706526029.git.sandipan.das@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/events/amd/core.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
+index 04f4b96dec6df..fd091b9dd7067 100644
+--- a/arch/x86/events/amd/core.c
++++ b/arch/x86/events/amd/core.c
+@@ -604,7 +604,6 @@ static void amd_pmu_cpu_dead(int cpu)
+
+ kfree(cpuhw->lbr_sel);
+ cpuhw->lbr_sel = NULL;
+- amd_pmu_cpu_reset(cpu);
+
+ if (!x86_pmu.amd_nb_constraints)
+ return;
+--
+2.43.0
+
--- /dev/null
+From 8585faf157c43f96371dab0d56bb46aa2aeff92b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jan 2024 15:19:07 +0800
+Subject: pinctrl: mediatek: Drop bogus slew rate register range for MT8186
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit 3a29c87548809405bcbc66acc69cbe6f15184d94 ]
+
+The MT8186 does not support configuring pin slew rate. This is evident
+from both the datasheet, and the fact that the driver points the slew
+rate register range at the GPIO direction register range.
+
+Drop the bogus setting.
+
+Fixes: 8b483bda1e46 ("pinctrl: add pinctrl driver on mt8186")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20240131071910.3950450-1-wenst@chromium.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-mt8186.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8186.c b/drivers/pinctrl/mediatek/pinctrl-mt8186.c
+index a02f7c3269707..09edcf47effec 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mt8186.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt8186.c
+@@ -1198,7 +1198,6 @@ static const struct mtk_pin_reg_calc mt8186_reg_cals[PINCTRL_PIN_REG_MAX] = {
+ [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt8186_pin_dir_range),
+ [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt8186_pin_di_range),
+ [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt8186_pin_do_range),
+- [PINCTRL_PIN_REG_SR] = MTK_RANGE(mt8186_pin_dir_range),
+ [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt8186_pin_smt_range),
+ [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt8186_pin_ies_range),
+ [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt8186_pin_pu_range),
+--
+2.43.0
+
--- /dev/null
+From 0943da0d83e7be109b02868123b580cd4b337341 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jan 2024 15:19:08 +0800
+Subject: pinctrl: mediatek: Drop bogus slew rate register range for MT8192
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit e15ab05a6b3ed42f2f43f8bd1a1abdbde64afecd ]
+
+The MT8192 does not support configuring pin slew rate. This is evident
+from both the datasheet, and the fact that the driver points the slew
+rate register range at the GPIO direction register range.
+
+Drop the bogus setting.
+
+Fixes: d32f38f2a8fc ("pinctrl: mediatek: Add pinctrl driver for mt8192")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20240131071910.3950450-2-wenst@chromium.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-mt8192.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8192.c b/drivers/pinctrl/mediatek/pinctrl-mt8192.c
+index 9695f4ec6aba9..f120268c00f56 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mt8192.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt8192.c
+@@ -1379,7 +1379,6 @@ static const struct mtk_pin_reg_calc mt8192_reg_cals[PINCTRL_PIN_REG_MAX] = {
+ [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt8192_pin_dir_range),
+ [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt8192_pin_di_range),
+ [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt8192_pin_do_range),
+- [PINCTRL_PIN_REG_SR] = MTK_RANGE(mt8192_pin_dir_range),
+ [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt8192_pin_smt_range),
+ [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt8192_pin_ies_range),
+ [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt8192_pin_pu_range),
+--
+2.43.0
+
--- /dev/null
+From 592c4e8872f513eaf290b2f5286223c369da2d9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Feb 2023 01:03:09 +0000
+Subject: pinctrl: renesas: r8a779g0: Add Audio SSI pins, groups, and functions
+
+From: Linh Phung <linh.phung.jy@renesas.com>
+
+[ Upstream commit b37d57e1daccbc1a0393d9207d5c48f9181fe85a ]
+
+Add pins, groups, and functions for the Serial Sound Interface (SSI) on
+the Renesas R-Car V4H (R8A779G0) SoC.
+
+Signed-off-by: Linh Phung <linh.phung.jy@renesas.com>
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/87bkmcang2.wl-kuninori.morimoto.gx@renesas.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Stable-dep-of: 68540257cdf1 ("pinctrl: renesas: r8a779g0: Add missing SCIF_CLK2 pin group/function")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/renesas/pfc-r8a779g0.c | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+diff --git a/drivers/pinctrl/renesas/pfc-r8a779g0.c b/drivers/pinctrl/renesas/pfc-r8a779g0.c
+index 43a63a21a6fb5..14774163df354 100644
+--- a/drivers/pinctrl/renesas/pfc-r8a779g0.c
++++ b/drivers/pinctrl/renesas/pfc-r8a779g0.c
+@@ -2360,6 +2360,22 @@ static const unsigned int scif_clk_mux[] = {
+ SCIF_CLK_MARK,
+ };
+
++/* - SSI ------------------------------------------------- */
++static const unsigned int ssi_data_pins[] = {
++ /* SSI_SD */
++ RCAR_GP_PIN(1, 20),
++};
++static const unsigned int ssi_data_mux[] = {
++ SSI_SD_MARK,
++};
++static const unsigned int ssi_ctrl_pins[] = {
++ /* SSI_SCK, SSI_WS */
++ RCAR_GP_PIN(1, 18), RCAR_GP_PIN(1, 19),
++};
++static const unsigned int ssi_ctrl_mux[] = {
++ SSI_SCK_MARK, SSI_WS_MARK,
++};
++
+ /* - TPU ------------------------------------------------------------------- */
+ static const unsigned int tpu_to0_pins[] = {
+ /* TPU0TO0 */
+@@ -2652,6 +2668,9 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
+ SH_PFC_PIN_GROUP(scif4_ctrl),
+ SH_PFC_PIN_GROUP(scif_clk),
+
++ SH_PFC_PIN_GROUP(ssi_data),
++ SH_PFC_PIN_GROUP(ssi_ctrl),
++
+ SH_PFC_PIN_GROUP(tpu_to0), /* suffix might be updated */
+ SH_PFC_PIN_GROUP(tpu_to0_a), /* suffix might be updated */
+ SH_PFC_PIN_GROUP(tpu_to1), /* suffix might be updated */
+@@ -2964,6 +2983,11 @@ static const char * const scif_clk_groups[] = {
+ "scif_clk",
+ };
+
++static const char * const ssi_groups[] = {
++ "ssi_data",
++ "ssi_ctrl",
++};
++
+ static const char * const tpu_groups[] = {
+ /* suffix might be updated */
+ "tpu_to0",
+@@ -3045,6 +3069,8 @@ static const struct sh_pfc_function pinmux_functions[] = {
+ SH_PFC_FUNCTION(scif4),
+ SH_PFC_FUNCTION(scif_clk),
+
++ SH_PFC_FUNCTION(ssi),
++
+ SH_PFC_FUNCTION(tpu),
+
+ SH_PFC_FUNCTION(tsn0),
+--
+2.43.0
+
--- /dev/null
+From b8a2f841d90ba98be2c1f8f03fe86586230c89d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Jan 2024 17:32:36 +0100
+Subject: pinctrl: renesas: r8a779g0: Add missing SCIF_CLK2 pin group/function
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 68540257cdf1d07ff8a649aa94c21c5804bbb9b0 ]
+
+R-Car V4H actually has two SCIF_CLK pins.
+The second pin provides the SCIF_CLK signal for HSCIF2 and SCIF4.
+
+Fixes: 050442ae4c74f830 ("pinctrl: renesas: r8a779g0: Add pins, groups and functions")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/6352ec9b63fdd38c2c70d8d203e46f21fbfeccdc.1705589612.git.geert+renesas@glider.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/renesas/pfc-r8a779g0.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/drivers/pinctrl/renesas/pfc-r8a779g0.c b/drivers/pinctrl/renesas/pfc-r8a779g0.c
+index 14774163df354..acf7664ea835b 100644
+--- a/drivers/pinctrl/renesas/pfc-r8a779g0.c
++++ b/drivers/pinctrl/renesas/pfc-r8a779g0.c
+@@ -2360,6 +2360,14 @@ static const unsigned int scif_clk_mux[] = {
+ SCIF_CLK_MARK,
+ };
+
++static const unsigned int scif_clk2_pins[] = {
++ /* SCIF_CLK2 */
++ RCAR_GP_PIN(8, 11),
++};
++static const unsigned int scif_clk2_mux[] = {
++ SCIF_CLK2_MARK,
++};
++
+ /* - SSI ------------------------------------------------- */
+ static const unsigned int ssi_data_pins[] = {
+ /* SSI_SD */
+@@ -2667,6 +2675,7 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
+ SH_PFC_PIN_GROUP(scif4_clk),
+ SH_PFC_PIN_GROUP(scif4_ctrl),
+ SH_PFC_PIN_GROUP(scif_clk),
++ SH_PFC_PIN_GROUP(scif_clk2),
+
+ SH_PFC_PIN_GROUP(ssi_data),
+ SH_PFC_PIN_GROUP(ssi_ctrl),
+@@ -2983,6 +2992,10 @@ static const char * const scif_clk_groups[] = {
+ "scif_clk",
+ };
+
++static const char * const scif_clk2_groups[] = {
++ "scif_clk2",
++};
++
+ static const char * const ssi_groups[] = {
+ "ssi_data",
+ "ssi_ctrl",
+@@ -3068,6 +3081,7 @@ static const struct sh_pfc_function pinmux_functions[] = {
+ SH_PFC_FUNCTION(scif3),
+ SH_PFC_FUNCTION(scif4),
+ SH_PFC_FUNCTION(scif_clk),
++ SH_PFC_FUNCTION(scif_clk2),
+
+ SH_PFC_FUNCTION(ssi),
+
+--
+2.43.0
+
--- /dev/null
+From ebbb6b9aa118f00466744902429c1e6bff125c6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Jan 2024 13:05:10 -0800
+Subject: pmdomain: qcom: rpmhpd: Drop SA8540P gfx.lvl
+
+From: Bjorn Andersson <quic_bjorande@quicinc.com>
+
+[ Upstream commit 883957bee580b723fd87d49ac73e0c84fc03a446 ]
+
+On SA8295P and SA8540P gfx.lvl is not provdied by rpmh, but rather is
+handled by an external regulator (max20411). Drop gfx.lvl from the list
+of power-domains exposed on this platform.
+
+Fixes: f68f1cb3437d ("soc: qcom: rpmhpd: add sc8280xp & sa8540p rpmh power-domains")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20240125-sa8295p-gpu-v4-4-7011c2a63037@quicinc.com
+Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/qcom/rpmhpd.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c
+index 9a90f241bb97f..6efe36aeb48e9 100644
+--- a/drivers/soc/qcom/rpmhpd.c
++++ b/drivers/soc/qcom/rpmhpd.c
+@@ -195,7 +195,6 @@ static struct rpmhpd *sa8540p_rpmhpds[] = {
+ [SC8280XP_CX] = &cx,
+ [SC8280XP_CX_AO] = &cx_ao,
+ [SC8280XP_EBI] = &ebi,
+- [SC8280XP_GFX] = &gfx,
+ [SC8280XP_LCX] = &lcx,
+ [SC8280XP_LMX] = &lmx,
+ [SC8280XP_MMCX] = &mmcx,
+--
+2.43.0
+
--- /dev/null
+From d77cd3de77f62f715afb7ccda9483a133e3d3868 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Feb 2024 23:39:47 +0100
+Subject: powercap: dtpm_cpu: Fix error check against freq_qos_add_request()
+
+From: Daniel Lezcano <daniel.lezcano@linaro.org>
+
+[ Upstream commit b50155cb0d609437236c88201206267835c6f965 ]
+
+The caller of the function freq_qos_add_request() checks again a non
+zero value but freq_qos_add_request() can return '1' if the request
+already exists. Therefore, the setup function fails while the QoS
+request actually did not failed.
+
+Fix that by changing the check against a negative value like all the
+other callers of the function.
+
+Fixes: 0e8f68d7f0485 ("Add CPU energy model based support")
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/powercap/dtpm_cpu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/powercap/dtpm_cpu.c b/drivers/powercap/dtpm_cpu.c
+index 9193c3b8edebe..ae7ee611978ba 100644
+--- a/drivers/powercap/dtpm_cpu.c
++++ b/drivers/powercap/dtpm_cpu.c
+@@ -219,7 +219,7 @@ static int __dtpm_cpu_setup(int cpu, struct dtpm *parent)
+ ret = freq_qos_add_request(&policy->constraints,
+ &dtpm_cpu->qos_req, FREQ_QOS_MAX,
+ pd->table[pd->nr_perf_states - 1].frequency);
+- if (ret)
++ if (ret < 0)
+ goto out_dtpm_unregister;
+
+ cpufreq_cpu_put(policy);
+--
+2.43.0
+
--- /dev/null
+From 4ded82c85017ca5997e473cdc628ad0d5bb6afb3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 23:34:08 +1100
+Subject: powerpc/embedded6xx: Fix no previous prototype for avr_uart_send()
+ etc.
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit 20933531be0577cdd782216858c26150dbc7936f ]
+
+Move the prototypes into mpc10x.h which is included by all the relevant
+C files, fixes:
+
+ arch/powerpc/platforms/embedded6xx/ls_uart.c:59:6: error: no previous prototype for 'avr_uart_configure'
+ arch/powerpc/platforms/embedded6xx/ls_uart.c:82:6: error: no previous prototype for 'avr_uart_send'
+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20240305123410.3306253-1-mpe@ellerman.id.au
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/embedded6xx/linkstation.c | 3 ---
+ arch/powerpc/platforms/embedded6xx/mpc10x.h | 3 +++
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c
+index 1830e1ac1f8f0..107a8b60ad0c9 100644
+--- a/arch/powerpc/platforms/embedded6xx/linkstation.c
++++ b/arch/powerpc/platforms/embedded6xx/linkstation.c
+@@ -99,9 +99,6 @@ static void __init linkstation_init_IRQ(void)
+ mpic_init(mpic);
+ }
+
+-extern void avr_uart_configure(void);
+-extern void avr_uart_send(const char);
+-
+ static void __noreturn linkstation_restart(char *cmd)
+ {
+ local_irq_disable();
+diff --git a/arch/powerpc/platforms/embedded6xx/mpc10x.h b/arch/powerpc/platforms/embedded6xx/mpc10x.h
+index 5ad12023e5628..ebc258fa4858d 100644
+--- a/arch/powerpc/platforms/embedded6xx/mpc10x.h
++++ b/arch/powerpc/platforms/embedded6xx/mpc10x.h
+@@ -156,4 +156,7 @@ int mpc10x_disable_store_gathering(struct pci_controller *hose);
+ /* For MPC107 boards that use the built-in openpic */
+ void mpc10x_set_openpic(void);
+
++void avr_uart_configure(void);
++void avr_uart_send(const char c);
++
+ #endif /* __PPC_KERNEL_MPC10X_H */
+--
+2.43.0
+
--- /dev/null
+From ec48f9b5d1339cdd14f4c08f1767ace18e2e09bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Feb 2024 14:58:37 +0100
+Subject: powerpc: Force inlining of arch_vmap_p{u/m}d_supported()
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit c5aebb53b32460bc52680dd4e2a2f6b84d5ea521 ]
+
+arch_vmap_pud_supported() and arch_vmap_pmd_supported() are
+expected to constant-fold to false when RADIX is not enabled.
+
+Force inlining in order to avoid following failure which
+leads to unexpected call of non-existing pud_set_huge() and
+pmd_set_huge() on powerpc 8xx.
+
+In function 'pud_huge_tests',
+ inlined from 'debug_vm_pgtable' at mm/debug_vm_pgtable.c:1399:2:
+./arch/powerpc/include/asm/vmalloc.h:9:33: warning: inlining failed in call to 'arch_vmap_pud_supported.isra': call is unlikely and code size would grow [-Winline]
+ 9 | #define arch_vmap_pud_supported arch_vmap_pud_supported
+ | ^~~~~~~~~~~~~~~~~~~~~~~
+./arch/powerpc/include/asm/vmalloc.h:10:20: note: in expansion of macro 'arch_vmap_pud_supported'
+ 10 | static inline bool arch_vmap_pud_supported(pgprot_t prot)
+ | ^~~~~~~~~~~~~~~~~~~~~~~
+./arch/powerpc/include/asm/vmalloc.h:9:33: note: called from here
+ 9 | #define arch_vmap_pud_supported arch_vmap_pud_supported
+mm/debug_vm_pgtable.c:458:14: note: in expansion of macro 'arch_vmap_pud_supported'
+ 458 | if (!arch_vmap_pud_supported(args->page_prot) ||
+ | ^~~~~~~~~~~~~~~~~~~~~~~
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202402131836.OU1TDuoi-lkp@intel.com/
+Fixes: 8309c9d71702 ("powerpc: inline huge vmap supported functions")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/bbd84ad52bf377e8d3b5865a906f2dc5d99964ba.1707832677.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/vmalloc.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/vmalloc.h b/arch/powerpc/include/asm/vmalloc.h
+index 4c69ece52a31e..59ed89890c902 100644
+--- a/arch/powerpc/include/asm/vmalloc.h
++++ b/arch/powerpc/include/asm/vmalloc.h
+@@ -7,14 +7,14 @@
+ #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP
+
+ #define arch_vmap_pud_supported arch_vmap_pud_supported
+-static inline bool arch_vmap_pud_supported(pgprot_t prot)
++static __always_inline bool arch_vmap_pud_supported(pgprot_t prot)
+ {
+ /* HPT does not cope with large pages in the vmalloc area */
+ return radix_enabled();
+ }
+
+ #define arch_vmap_pmd_supported arch_vmap_pmd_supported
+-static inline bool arch_vmap_pmd_supported(pgprot_t prot)
++static __always_inline bool arch_vmap_pmd_supported(pgprot_t prot)
+ {
+ return radix_enabled();
+ }
+--
+2.43.0
+
--- /dev/null
+From 85b058673bec8bd2388e6191587de0e80046d9f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 17:58:47 +0530
+Subject: powerpc/hv-gpci: Fix the H_GET_PERF_COUNTER_INFO hcall return value
+ checks
+
+From: Kajol Jain <kjain@linux.ibm.com>
+
+[ Upstream commit ad86d7ee43b22aa2ed60fb982ae94b285c1be671 ]
+
+Running event hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/
+in one of the system throws below error:
+
+ ---Logs---
+ # perf list | grep hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles
+ hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=?/[Kernel PMU event]
+
+ # perf stat -v -e hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/ sleep 2
+Using CPUID 00800200
+Control descriptor is not initialized
+Warning:
+hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/ event is not supported by the kernel.
+failed to read counter hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/
+
+ Performance counter stats for 'system wide':
+
+ <not supported> hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/
+
+ 2.000700771 seconds time elapsed
+
+The above error is because of the hcall failure as required
+permission "Enable Performance Information Collection" is not set.
+Based on current code, single_gpci_request function did not check the
+error type incase hcall fails and by default returns EINVAL. But we can
+have other reasons for hcall failures like H_AUTHORITY/H_PARAMETER with
+detail_rc as GEN_BUF_TOO_SMALL, for which we need to act accordingly.
+
+Fix this issue by adding new checks in the single_gpci_request and
+h_gpci_event_init functions.
+
+Result after fix patch changes:
+
+ # perf stat -e hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/ sleep 2
+Error:
+No permission to enable hv_gpci/dispatch_timebase_by_processor_processor_time_in_timebase_cycles,phys_processor_idx=0/ event.
+
+Fixes: 220a0c609ad1 ("powerpc/perf: Add support for the hv gpci (get performance counter info) interface")
+Reported-by: Akanksha J N <akanksha@linux.ibm.com>
+Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20240229122847.101162-1-kjain@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/perf/hv-gpci.c | 29 +++++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c
+index 7ff8ff3509f5f..943248a0e9a9d 100644
+--- a/arch/powerpc/perf/hv-gpci.c
++++ b/arch/powerpc/perf/hv-gpci.c
+@@ -164,6 +164,20 @@ static unsigned long single_gpci_request(u32 req, u32 starting_index,
+
+ ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO,
+ virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE);
++
++ /*
++ * ret value as 'H_PARAMETER' with detail_rc as 'GEN_BUF_TOO_SMALL',
++ * specifies that the current buffer size cannot accommodate
++ * all the information and a partial buffer returned.
++ * Since in this function we are only accessing data for a given starting index,
++ * we don't need to accommodate whole data and can get required count by
++ * accessing first entry data.
++ * Hence hcall fails only incase the ret value is other than H_SUCCESS or
++ * H_PARAMETER with detail_rc value as GEN_BUF_TOO_SMALL(0x1B).
++ */
++ if (ret == H_PARAMETER && be32_to_cpu(arg->params.detail_rc) == 0x1B)
++ ret = 0;
++
+ if (ret) {
+ pr_devel("hcall failed: 0x%lx\n", ret);
+ goto out;
+@@ -228,6 +242,7 @@ static int h_gpci_event_init(struct perf_event *event)
+ {
+ u64 count;
+ u8 length;
++ unsigned long ret;
+
+ /* Not our event */
+ if (event->attr.type != event->pmu->type)
+@@ -258,13 +273,23 @@ static int h_gpci_event_init(struct perf_event *event)
+ }
+
+ /* check if the request works... */
+- if (single_gpci_request(event_get_request(event),
++ ret = single_gpci_request(event_get_request(event),
+ event_get_starting_index(event),
+ event_get_secondary_index(event),
+ event_get_counter_info_version(event),
+ event_get_offset(event),
+ length,
+- &count)) {
++ &count);
++
++ /*
++ * ret value as H_AUTHORITY implies that partition is not permitted to retrieve
++ * performance information, and required to set
++ * "Enable Performance Information Collection" option.
++ */
++ if (ret == H_AUTHORITY)
++ return -EPERM;
++
++ if (ret) {
+ pr_devel("gpci hcall failed\n");
+ return -EINVAL;
+ }
+--
+2.43.0
+
--- /dev/null
+From 42bfbe01d5981ee06f5bb533abfae8ba928e361b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Dec 2022 21:34:49 +0800
+Subject: powerpc/pseries: Fix potential memleak in papr_get_attr()
+
+From: Qiheng Lin <linqiheng@huawei.com>
+
+[ Upstream commit cda9c0d556283e2d4adaa9960b2dc19b16156bae ]
+
+`buf` is allocated in papr_get_attr(), and krealloc() of `buf`
+could fail. We need to free the original `buf` in the case of failure.
+
+Fixes: 3c14b73454cf ("powerpc/pseries: Interface to represent PAPR firmware attributes")
+Signed-off-by: Qiheng Lin <linqiheng@huawei.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20221208133449.16284-1-linqiheng@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/pseries/papr_platform_attributes.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/arch/powerpc/platforms/pseries/papr_platform_attributes.c b/arch/powerpc/platforms/pseries/papr_platform_attributes.c
+index 526c621b098be..eea2041b270b5 100644
+--- a/arch/powerpc/platforms/pseries/papr_platform_attributes.c
++++ b/arch/powerpc/platforms/pseries/papr_platform_attributes.c
+@@ -101,10 +101,12 @@ static int papr_get_attr(u64 id, struct energy_scale_attribute *esi)
+ esi_buf_size = ESI_HDR_SIZE + (CURR_MAX_ESI_ATTRS * max_esi_attrs);
+
+ temp_buf = krealloc(buf, esi_buf_size, GFP_KERNEL);
+- if (temp_buf)
++ if (temp_buf) {
+ buf = temp_buf;
+- else
+- return -ENOMEM;
++ } else {
++ ret = -ENOMEM;
++ goto out_buf;
++ }
+
+ goto retry;
+ }
+--
+2.43.0
+
--- /dev/null
+From b8f6f3827d6326a4706af5116c34b020d411072d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Feb 2024 14:47:00 +0106
+Subject: printk: Disable passing console lock owner completely during panic()
+
+From: Petr Mladek <pmladek@suse.com>
+
+[ Upstream commit d04d5882cd678b898a9d7c5aee6afbe9e6e77fcd ]
+
+The commit d51507098ff91 ("printk: disable optimistic spin
+during panic") added checks to avoid becoming a console waiter
+if a panic is in progress.
+
+However, the transition to panic can occur while there is
+already a waiter. The current owner should not pass the lock to
+the waiter because it might get stopped or blocked anytime.
+
+Also the panic context might pass the console lock owner to an
+already stopped waiter by mistake. It might happen when
+console_flush_on_panic() ignores the current lock owner, for
+example:
+
+CPU0 CPU1
+---- ----
+console_lock_spinning_enable()
+ console_trylock_spinning()
+ [CPU1 now console waiter]
+NMI: panic()
+ panic_other_cpus_shutdown()
+ [stopped as console waiter]
+ console_flush_on_panic()
+ console_lock_spinning_enable()
+ [print 1 record]
+ console_lock_spinning_disable_and_check()
+ [handover to stopped CPU1]
+
+This results in panic() not flushing the panic messages.
+
+Fix these problems by disabling all spinning operations
+completely during panic().
+
+Another advantage is that it prevents possible deadlocks caused
+by "console_owner_lock". The panic() context does not need to
+take it any longer. The lockless checks are safe because the
+functions become NOPs when they see the panic in progress. All
+operations manipulating the state are still synchronized by the
+lock even when non-panic CPUs would notice the panic
+synchronously.
+
+The current owner might stay spinning. But non-panic() CPUs
+would get stopped anyway and the panic context will never start
+spinning.
+
+Fixes: dbdda842fe96 ("printk: Add console owner and waiter logic to load balance console writes")
+Signed-off-by: John Ogness <john.ogness@linutronix.de>
+Link: https://lore.kernel.org/r/20240207134103.1357162-12-john.ogness@linutronix.de
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/printk/printk.c | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
+index cc53fb77f77cc..981cdb00b8722 100644
+--- a/kernel/printk/printk.c
++++ b/kernel/printk/printk.c
+@@ -1797,10 +1797,23 @@ static bool console_waiter;
+ */
+ static void console_lock_spinning_enable(void)
+ {
++ /*
++ * Do not use spinning in panic(). The panic CPU wants to keep the lock.
++ * Non-panic CPUs abandon the flush anyway.
++ *
++ * Just keep the lockdep annotation. The panic-CPU should avoid
++ * taking console_owner_lock because it might cause a deadlock.
++ * This looks like the easiest way how to prevent false lockdep
++ * reports without handling races a lockless way.
++ */
++ if (panic_in_progress())
++ goto lockdep;
++
+ raw_spin_lock(&console_owner_lock);
+ console_owner = current;
+ raw_spin_unlock(&console_owner_lock);
+
++lockdep:
+ /* The waiter may spin on us after setting console_owner */
+ spin_acquire(&console_owner_dep_map, 0, 0, _THIS_IP_);
+ }
+@@ -1824,6 +1837,22 @@ static int console_lock_spinning_disable_and_check(void)
+ {
+ int waiter;
+
++ /*
++ * Ignore spinning waiters during panic() because they might get stopped
++ * or blocked at any time,
++ *
++ * It is safe because nobody is allowed to start spinning during panic
++ * in the first place. If there has been a waiter then non panic CPUs
++ * might stay spinning. They would get stopped anyway. The panic context
++ * will never start spinning and an interrupted spin on panic CPU will
++ * never continue.
++ */
++ if (panic_in_progress()) {
++ /* Keep lockdep happy. */
++ spin_release(&console_owner_dep_map, _THIS_IP_);
++ return 0;
++ }
++
+ raw_spin_lock(&console_owner_lock);
+ waiter = READ_ONCE(console_waiter);
+ console_owner = NULL;
+--
+2.43.0
+
--- /dev/null
+From b1536c5f3f75aa111203525f361ba352b37e2172 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 10:26:15 -0800
+Subject: pstore: inode: Convert mutex usage to guard(mutex)
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit e2eeddefb046dbc771a6fa426f7f98fb25adfe68 ]
+
+Replace open-coded mutex handling with cleanup.h guard(mutex) and
+scoped_guard(mutex, ...).
+
+Cc: Guilherme G. Piccoli <gpiccoli@igalia.com>
+Cc: Tony Luck <tony.luck@intel.com>
+Cc: <linux-hardening@vger.kernel.org>
+Link: https://lore.kernel.org/r/20231205182622.1329923-2-keescook@chromium.org
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Stable-dep-of: a43e0fc5e913 ("pstore: inode: Only d_invalidate() is needed")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/pstore/inode.c | 76 +++++++++++++++++++----------------------------
+ 1 file changed, 31 insertions(+), 45 deletions(-)
+
+diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
+index ffbadb8b3032d..05ddfb37b15e1 100644
+--- a/fs/pstore/inode.c
++++ b/fs/pstore/inode.c
+@@ -182,25 +182,21 @@ static int pstore_unlink(struct inode *dir, struct dentry *dentry)
+ {
+ struct pstore_private *p = d_inode(dentry)->i_private;
+ struct pstore_record *record = p->record;
+- int rc = 0;
+
+ if (!record->psi->erase)
+ return -EPERM;
+
+ /* Make sure we can't race while removing this file. */
+- mutex_lock(&records_list_lock);
+- if (!list_empty(&p->list))
+- list_del_init(&p->list);
+- else
+- rc = -ENOENT;
+- p->dentry = NULL;
+- mutex_unlock(&records_list_lock);
+- if (rc)
+- return rc;
+-
+- mutex_lock(&record->psi->read_mutex);
+- record->psi->erase(record);
+- mutex_unlock(&record->psi->read_mutex);
++ scoped_guard(mutex, &records_list_lock) {
++ if (!list_empty(&p->list))
++ list_del_init(&p->list);
++ else
++ return -ENOENT;
++ p->dentry = NULL;
++ }
++
++ scoped_guard(mutex, &record->psi->read_mutex)
++ record->psi->erase(record);
+
+ return simple_unlink(dir, dentry);
+ }
+@@ -292,19 +288,16 @@ static struct dentry *psinfo_lock_root(void)
+ {
+ struct dentry *root;
+
+- mutex_lock(&pstore_sb_lock);
++ guard(mutex)(&pstore_sb_lock);
+ /*
+ * Having no backend is fine -- no records appear.
+ * Not being mounted is fine -- nothing to do.
+ */
+- if (!psinfo || !pstore_sb) {
+- mutex_unlock(&pstore_sb_lock);
++ if (!psinfo || !pstore_sb)
+ return NULL;
+- }
+
+ root = pstore_sb->s_root;
+ inode_lock(d_inode(root));
+- mutex_unlock(&pstore_sb_lock);
+
+ return root;
+ }
+@@ -319,19 +312,19 @@ int pstore_put_backend_records(struct pstore_info *psi)
+ if (!root)
+ return 0;
+
+- mutex_lock(&records_list_lock);
+- list_for_each_entry_safe(pos, tmp, &records_list, list) {
+- if (pos->record->psi == psi) {
+- list_del_init(&pos->list);
+- rc = simple_unlink(d_inode(root), pos->dentry);
+- if (WARN_ON(rc))
+- break;
+- d_drop(pos->dentry);
+- dput(pos->dentry);
+- pos->dentry = NULL;
++ scoped_guard(mutex, &records_list_lock) {
++ list_for_each_entry_safe(pos, tmp, &records_list, list) {
++ if (pos->record->psi == psi) {
++ list_del_init(&pos->list);
++ rc = simple_unlink(d_inode(root), pos->dentry);
++ if (WARN_ON(rc))
++ break;
++ d_drop(pos->dentry);
++ dput(pos->dentry);
++ pos->dentry = NULL;
++ }
+ }
+ }
+- mutex_unlock(&records_list_lock);
+
+ inode_unlock(d_inode(root));
+
+@@ -355,20 +348,20 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record)
+ if (WARN_ON(!inode_is_locked(d_inode(root))))
+ return -EINVAL;
+
+- rc = -EEXIST;
++ guard(mutex)(&records_list_lock);
++
+ /* Skip records that are already present in the filesystem. */
+- mutex_lock(&records_list_lock);
+ list_for_each_entry(pos, &records_list, list) {
+ if (pos->record->type == record->type &&
+ pos->record->id == record->id &&
+ pos->record->psi == record->psi)
+- goto fail;
++ return -EEXIST;
+ }
+
+ rc = -ENOMEM;
+ inode = pstore_get_inode(root->d_sb);
+ if (!inode)
+- goto fail;
++ return -ENOMEM;
+ inode->i_mode = S_IFREG | 0444;
+ inode->i_fop = &pstore_file_operations;
+ scnprintf(name, sizeof(name), "%s-%s-%llu%s",
+@@ -395,7 +388,6 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record)
+ d_add(dentry, inode);
+
+ list_add(&private->list, &records_list);
+- mutex_unlock(&records_list_lock);
+
+ return 0;
+
+@@ -403,8 +395,6 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record)
+ free_pstore_private(private);
+ fail_inode:
+ iput(inode);
+-fail:
+- mutex_unlock(&records_list_lock);
+ return rc;
+ }
+
+@@ -450,9 +440,8 @@ static int pstore_fill_super(struct super_block *sb, void *data, int silent)
+ if (!sb->s_root)
+ return -ENOMEM;
+
+- mutex_lock(&pstore_sb_lock);
+- pstore_sb = sb;
+- mutex_unlock(&pstore_sb_lock);
++ scoped_guard(mutex, &pstore_sb_lock)
++ pstore_sb = sb;
+
+ pstore_get_records(0);
+
+@@ -467,17 +456,14 @@ static struct dentry *pstore_mount(struct file_system_type *fs_type,
+
+ static void pstore_kill_sb(struct super_block *sb)
+ {
+- mutex_lock(&pstore_sb_lock);
++ guard(mutex)(&pstore_sb_lock);
+ WARN_ON(pstore_sb && pstore_sb != sb);
+
+ kill_litter_super(sb);
+ pstore_sb = NULL;
+
+- mutex_lock(&records_list_lock);
++ guard(mutex)(&records_list_lock);
+ INIT_LIST_HEAD(&records_list);
+- mutex_unlock(&records_list_lock);
+-
+- mutex_unlock(&pstore_sb_lock);
+ }
+
+ static struct file_system_type pstore_fs_type = {
+--
+2.43.0
+
--- /dev/null
+From aa2e518baf199f6141caa634aa7d3d0485f8c2ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Feb 2024 09:48:46 -0800
+Subject: pstore: inode: Only d_invalidate() is needed
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit a43e0fc5e9134a46515de2f2f8d4100b74e50de3 ]
+
+Unloading a modular pstore backend with records in pstorefs would
+trigger the dput() double-drop warning:
+
+ WARNING: CPU: 0 PID: 2569 at fs/dcache.c:762 dput.part.0+0x3f3/0x410
+
+Using the combo of d_drop()/dput() (as mentioned in
+Documentation/filesystems/vfs.rst) isn't the right approach here, and
+leads to the reference counting problem seen above. Use d_invalidate()
+and update the code to not bother checking for error codes that can
+never happen.
+
+Suggested-by: Alexander Viro <viro@zeniv.linux.org.uk>
+Fixes: 609e28bb139e ("pstore: Remove filesystem records when backend is unregistered")
+Signed-off-by: Kees Cook <keescook@chromium.org>
+---
+Cc: "Guilherme G. Piccoli" <gpiccoli@igalia.com>
+Cc: Tony Luck <tony.luck@intel.com>
+Cc: linux-hardening@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/pstore/inode.c | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
+index 05ddfb37b15e1..ea3f104371d62 100644
+--- a/fs/pstore/inode.c
++++ b/fs/pstore/inode.c
+@@ -306,7 +306,6 @@ int pstore_put_backend_records(struct pstore_info *psi)
+ {
+ struct pstore_private *pos, *tmp;
+ struct dentry *root;
+- int rc = 0;
+
+ root = psinfo_lock_root();
+ if (!root)
+@@ -316,11 +315,8 @@ int pstore_put_backend_records(struct pstore_info *psi)
+ list_for_each_entry_safe(pos, tmp, &records_list, list) {
+ if (pos->record->psi == psi) {
+ list_del_init(&pos->list);
+- rc = simple_unlink(d_inode(root), pos->dentry);
+- if (WARN_ON(rc))
+- break;
+- d_drop(pos->dentry);
+- dput(pos->dentry);
++ d_invalidate(pos->dentry);
++ simple_unlink(d_inode(root), pos->dentry);
+ pos->dentry = NULL;
+ }
+ }
+@@ -328,7 +324,7 @@ int pstore_put_backend_records(struct pstore_info *psi)
+
+ inode_unlock(d_inode(root));
+
+- return rc;
++ return 0;
+ }
+
+ /*
+--
+2.43.0
+
--- /dev/null
+From 11b398a39657829da4adbc1d579bf5237d75938a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Mar 2023 19:54:16 +0100
+Subject: pwm: atmel-hlcdc: Convert to platform remove callback returning void
+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 5fce94170ad8a67b839f3dd8e8e8a87039ba0251 ]
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is (mostly) ignored
+and this typically results in resource leaks. To improve here there is a
+quest to make the remove callback return void. In the first step of this
+quest all drivers are converted to .remove_new() which already returns
+void.
+
+Trivially convert this driver from always returning zero in the remove
+callback to the void returning variant.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Stable-dep-of: e25ac87d3f83 ("pwm: atmel-hlcdc: Fix clock imbalance related to suspend support")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-atmel-hlcdc.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/pwm/pwm-atmel-hlcdc.c b/drivers/pwm/pwm-atmel-hlcdc.c
+index a43b2babc8093..96a709a9d49a8 100644
+--- a/drivers/pwm/pwm-atmel-hlcdc.c
++++ b/drivers/pwm/pwm-atmel-hlcdc.c
+@@ -278,15 +278,13 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev)
+ return 0;
+ }
+
+-static int atmel_hlcdc_pwm_remove(struct platform_device *pdev)
++static void atmel_hlcdc_pwm_remove(struct platform_device *pdev)
+ {
+ struct atmel_hlcdc_pwm *chip = platform_get_drvdata(pdev);
+
+ pwmchip_remove(&chip->chip);
+
+ clk_disable_unprepare(chip->hlcdc->periph_clk);
+-
+- return 0;
+ }
+
+ static const struct of_device_id atmel_hlcdc_pwm_dt_ids[] = {
+@@ -301,7 +299,7 @@ static struct platform_driver atmel_hlcdc_pwm_driver = {
+ .pm = &atmel_hlcdc_pwm_pm_ops,
+ },
+ .probe = atmel_hlcdc_pwm_probe,
+- .remove = atmel_hlcdc_pwm_remove,
++ .remove_new = atmel_hlcdc_pwm_remove,
+ };
+ module_platform_driver(atmel_hlcdc_pwm_driver);
+
+--
+2.43.0
+
--- /dev/null
+From d660a3b20e80f09a2d13ac9bc3229bedaa472ebf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Jan 2024 13:04:33 +0100
+Subject: pwm: atmel-hlcdc: Fix clock imbalance related to suspend support
+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 e25ac87d3f831fed002c34aadddaf4ebb4ea45ec ]
+
+The suspend callback disables the periph clock when the PWM is enabled
+and resume reenables this clock if the PWM was disabled before. Judging
+from the code comment it's suspend that is wrong here. Fix accordingly.
+
+Fixes: f9bb9da7c09d ("pwm: atmel-hlcdc: Implement the suspend/resume hooks")
+Reviewed-by: Claudiu Beznea <claudiu.beznea@tuxon.dev>
+Link: https://lore.kernel.org/r/b51ea92b0a45eff3dc83b08adefd43d930df996c.1706269232.git.u.kleine-koenig@pengutronix.de
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-atmel-hlcdc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pwm/pwm-atmel-hlcdc.c b/drivers/pwm/pwm-atmel-hlcdc.c
+index 4d0b859d0ac13..3e9c94a8d7f72 100644
+--- a/drivers/pwm/pwm-atmel-hlcdc.c
++++ b/drivers/pwm/pwm-atmel-hlcdc.c
+@@ -186,7 +186,7 @@ static int atmel_hlcdc_pwm_suspend(struct device *dev)
+ struct atmel_hlcdc_pwm *atmel = dev_get_drvdata(dev);
+
+ /* Keep the periph clock enabled if the PWM is still running. */
+- if (pwm_is_enabled(&atmel->chip.pwms[0]))
++ if (!pwm_is_enabled(&atmel->chip.pwms[0]))
+ clk_disable_unprepare(atmel->hlcdc->periph_clk);
+
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From 00959cbf82606d3ecb4432eca948993d77076a44 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Jul 2023 22:56:15 +0200
+Subject: pwm: atmel-hlcdc: Use consistent variable naming
+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 aecab554b6ffa9a94ba796031eb39ea20eb60fb3 ]
+
+In PWM drivers the variable name "chip" is usually only used for struct
+pwm_chip pointers. This driver however used "chip" for its driver data
+and pwm_chip pointers are named "chip", too, when there is no driver
+data around and "c" otherwise. Instead use "atmel" for driver data and
+always "chip" for pwm_chips.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Reviewed-by: Claudiu Beznea <claudiu.beznea@tuxon.dev>
+[thierry.reding@gmail.com: replace ddata by atmel]
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+Stable-dep-of: e25ac87d3f83 ("pwm: atmel-hlcdc: Fix clock imbalance related to suspend support")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-atmel-hlcdc.c | 65 ++++++++++++++++++-----------------
+ 1 file changed, 33 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/pwm/pwm-atmel-hlcdc.c b/drivers/pwm/pwm-atmel-hlcdc.c
+index 96a709a9d49a8..4d0b859d0ac13 100644
+--- a/drivers/pwm/pwm-atmel-hlcdc.c
++++ b/drivers/pwm/pwm-atmel-hlcdc.c
+@@ -38,11 +38,11 @@ static inline struct atmel_hlcdc_pwm *to_atmel_hlcdc_pwm(struct pwm_chip *chip)
+ return container_of(chip, struct atmel_hlcdc_pwm, chip);
+ }
+
+-static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm,
++static int atmel_hlcdc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ const struct pwm_state *state)
+ {
+- struct atmel_hlcdc_pwm *chip = to_atmel_hlcdc_pwm(c);
+- struct atmel_hlcdc *hlcdc = chip->hlcdc;
++ struct atmel_hlcdc_pwm *atmel = to_atmel_hlcdc_pwm(chip);
++ struct atmel_hlcdc *hlcdc = atmel->hlcdc;
+ unsigned int status;
+ int ret;
+
+@@ -54,7 +54,7 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm,
+ u32 pwmcfg;
+ int pres;
+
+- if (!chip->errata || !chip->errata->slow_clk_erratum) {
++ if (!atmel->errata || !atmel->errata->slow_clk_erratum) {
+ clk_freq = clk_get_rate(new_clk);
+ if (!clk_freq)
+ return -EINVAL;
+@@ -64,7 +64,7 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm,
+ }
+
+ /* Errata: cannot use slow clk on some IP revisions */
+- if ((chip->errata && chip->errata->slow_clk_erratum) ||
++ if ((atmel->errata && atmel->errata->slow_clk_erratum) ||
+ clk_period_ns > state->period) {
+ new_clk = hlcdc->sys_clk;
+ clk_freq = clk_get_rate(new_clk);
+@@ -77,8 +77,8 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm,
+
+ for (pres = 0; pres <= ATMEL_HLCDC_PWMPS_MAX; pres++) {
+ /* Errata: cannot divide by 1 on some IP revisions */
+- if (!pres && chip->errata &&
+- chip->errata->div1_clk_erratum)
++ if (!pres && atmel->errata &&
++ atmel->errata->div1_clk_erratum)
+ continue;
+
+ if ((clk_period_ns << pres) >= state->period)
+@@ -90,7 +90,7 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm,
+
+ pwmcfg = ATMEL_HLCDC_PWMPS(pres);
+
+- if (new_clk != chip->cur_clk) {
++ if (new_clk != atmel->cur_clk) {
+ u32 gencfg = 0;
+ int ret;
+
+@@ -98,8 +98,8 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm,
+ if (ret)
+ return ret;
+
+- clk_disable_unprepare(chip->cur_clk);
+- chip->cur_clk = new_clk;
++ clk_disable_unprepare(atmel->cur_clk);
++ atmel->cur_clk = new_clk;
+
+ if (new_clk == hlcdc->sys_clk)
+ gencfg = ATMEL_HLCDC_CLKPWMSEL;
+@@ -160,8 +160,8 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm,
+ if (ret)
+ return ret;
+
+- clk_disable_unprepare(chip->cur_clk);
+- chip->cur_clk = NULL;
++ clk_disable_unprepare(atmel->cur_clk);
++ atmel->cur_clk = NULL;
+ }
+
+ return 0;
+@@ -183,31 +183,32 @@ static const struct atmel_hlcdc_pwm_errata atmel_hlcdc_pwm_sama5d3_errata = {
+ #ifdef CONFIG_PM_SLEEP
+ static int atmel_hlcdc_pwm_suspend(struct device *dev)
+ {
+- struct atmel_hlcdc_pwm *chip = dev_get_drvdata(dev);
++ struct atmel_hlcdc_pwm *atmel = dev_get_drvdata(dev);
+
+ /* Keep the periph clock enabled if the PWM is still running. */
+- if (pwm_is_enabled(&chip->chip.pwms[0]))
+- clk_disable_unprepare(chip->hlcdc->periph_clk);
++ if (pwm_is_enabled(&atmel->chip.pwms[0]))
++ clk_disable_unprepare(atmel->hlcdc->periph_clk);
+
+ return 0;
+ }
+
+ static int atmel_hlcdc_pwm_resume(struct device *dev)
+ {
+- struct atmel_hlcdc_pwm *chip = dev_get_drvdata(dev);
++ struct atmel_hlcdc_pwm *atmel = dev_get_drvdata(dev);
+ struct pwm_state state;
+ int ret;
+
+- pwm_get_state(&chip->chip.pwms[0], &state);
++ pwm_get_state(&atmel->chip.pwms[0], &state);
+
+ /* Re-enable the periph clock it was stopped during suspend. */
+ if (!state.enabled) {
+- ret = clk_prepare_enable(chip->hlcdc->periph_clk);
++ ret = clk_prepare_enable(atmel->hlcdc->periph_clk);
+ if (ret)
+ return ret;
+ }
+
+- return atmel_hlcdc_pwm_apply(&chip->chip, &chip->chip.pwms[0], &state);
++ return atmel_hlcdc_pwm_apply(&atmel->chip, &atmel->chip.pwms[0],
++ &state);
+ }
+ #endif
+
+@@ -244,14 +245,14 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev)
+ {
+ const struct of_device_id *match;
+ struct device *dev = &pdev->dev;
+- struct atmel_hlcdc_pwm *chip;
++ struct atmel_hlcdc_pwm *atmel;
+ struct atmel_hlcdc *hlcdc;
+ int ret;
+
+ hlcdc = dev_get_drvdata(dev->parent);
+
+- chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+- if (!chip)
++ atmel = devm_kzalloc(dev, sizeof(*atmel), GFP_KERNEL);
++ if (!atmel)
+ return -ENOMEM;
+
+ ret = clk_prepare_enable(hlcdc->periph_clk);
+@@ -260,31 +261,31 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev)
+
+ match = of_match_node(atmel_hlcdc_dt_ids, dev->parent->of_node);
+ if (match)
+- chip->errata = match->data;
++ atmel->errata = match->data;
+
+- chip->hlcdc = hlcdc;
+- chip->chip.ops = &atmel_hlcdc_pwm_ops;
+- chip->chip.dev = dev;
+- chip->chip.npwm = 1;
++ atmel->hlcdc = hlcdc;
++ atmel->chip.ops = &atmel_hlcdc_pwm_ops;
++ atmel->chip.dev = dev;
++ atmel->chip.npwm = 1;
+
+- ret = pwmchip_add(&chip->chip);
++ ret = pwmchip_add(&atmel->chip);
+ if (ret) {
+ clk_disable_unprepare(hlcdc->periph_clk);
+ return ret;
+ }
+
+- platform_set_drvdata(pdev, chip);
++ platform_set_drvdata(pdev, atmel);
+
+ return 0;
+ }
+
+ static void atmel_hlcdc_pwm_remove(struct platform_device *pdev)
+ {
+- struct atmel_hlcdc_pwm *chip = platform_get_drvdata(pdev);
++ struct atmel_hlcdc_pwm *atmel = platform_get_drvdata(pdev);
+
+- pwmchip_remove(&chip->chip);
++ pwmchip_remove(&atmel->chip);
+
+- clk_disable_unprepare(chip->hlcdc->periph_clk);
++ clk_disable_unprepare(atmel->hlcdc->periph_clk);
+ }
+
+ static const struct of_device_id atmel_hlcdc_pwm_dt_ids[] = {
+--
+2.43.0
+
--- /dev/null
+From ffe0ce07b3f3e8536c69429cfd4331842fadf044 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 Feb 2024 22:20:43 +0100
+Subject: pwm: sti: Fix capture for st,pwm-num-chan < st,capture-num-chan
+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 5f623835584f1c8d1030666796f40c47a448ce0b ]
+
+The driver only used the number of pwm channels to set the pwm_chip's
+npwm member. The result is that if there are more capture channels than
+PWM channels specified in the device tree, only a part of the capture
+channel is usable. Fix that by passing the bigger channel count to the
+pwm framework. This makes it possible that the .apply() callback is
+called with .hwpwm >= pwm_num_devs, catch that case and return an error
+code.
+
+Fixes: c97267ae831d ("pwm: sti: Add PWM capture callback")
+Link: https://lore.kernel.org/r/20240204212043.2951852-2-u.kleine-koenig@pengutronix.de
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm-sti.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pwm/pwm-sti.c b/drivers/pwm/pwm-sti.c
+index 652fdb8dc7bfa..0a7920cbd4949 100644
+--- a/drivers/pwm/pwm-sti.c
++++ b/drivers/pwm/pwm-sti.c
+@@ -395,8 +395,17 @@ static int sti_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm,
+ static int sti_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ const struct pwm_state *state)
+ {
++ struct sti_pwm_chip *pc = to_sti_pwmchip(chip);
++ struct sti_pwm_compat_data *cdata = pc->cdata;
++ struct device *dev = pc->dev;
+ int err;
+
++ if (pwm->hwpwm >= cdata->pwm_num_devs) {
++ dev_err(dev, "device %u is not valid for pwm mode\n",
++ pwm->hwpwm);
++ return -EINVAL;
++ }
++
+ if (state->polarity != PWM_POLARITY_NORMAL)
+ return -EINVAL;
+
+@@ -647,7 +656,7 @@ static int sti_pwm_probe(struct platform_device *pdev)
+
+ pc->chip.dev = dev;
+ pc->chip.ops = &sti_pwm_ops;
+- pc->chip.npwm = pc->cdata->pwm_num_devs;
++ pc->chip.npwm = max(cdata->pwm_num_devs, cdata->cpt_num_devs);
+
+ for (i = 0; i < cdata->cpt_num_devs; i++) {
+ struct sti_cpt_ddata *ddata = &cdata->ddata[i];
+--
+2.43.0
+
--- /dev/null
+From 5b73189ccdd77044d8e40d72ead26a69f8863539 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Feb 2024 16:18:52 +0800
+Subject: quota: Fix potential NULL pointer dereference
+
+From: Wang Jianjian <wangjianjian3@huawei.com>
+
+[ Upstream commit d0aa72604fbd80c8aabb46eda00535ed35570f1f ]
+
+Below race may cause NULL pointer dereference
+
+P1 P2
+dquot_free_inode quota_off
+ drop_dquot_ref
+ remove_dquot_ref
+ dquots = i_dquot(inode)
+ dquots = i_dquot(inode)
+ srcu_read_lock
+ dquots[cnt]) != NULL (1)
+ dquots[type] = NULL (2)
+ spin_lock(&dquots[cnt]->dq_dqb_lock) (3)
+ ....
+
+If dquot_free_inode(or other routines) checks inode's quota pointers (1)
+before quota_off sets it to NULL(2) and use it (3) after that, NULL pointer
+dereference will be triggered.
+
+So let's fix it by using a temporary pointer to avoid this issue.
+
+Signed-off-by: Wang Jianjian <wangjianjian3@huawei.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Message-Id: <20240202081852.2514092-1-wangjianjian3@huawei.com>
+Stable-dep-of: 179b8c97ebf6 ("quota: Fix rcu annotations of inode dquot pointers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/quota/dquot.c | 98 ++++++++++++++++++++++++++++--------------------
+ 1 file changed, 57 insertions(+), 41 deletions(-)
+
+diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
+index 730d8ffc4928a..44c4da364c994 100644
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -399,15 +399,17 @@ int dquot_mark_dquot_dirty(struct dquot *dquot)
+ EXPORT_SYMBOL(dquot_mark_dquot_dirty);
+
+ /* Dirtify all the dquots - this can block when journalling */
+-static inline int mark_all_dquot_dirty(struct dquot * const *dquot)
++static inline int mark_all_dquot_dirty(struct dquot * const *dquots)
+ {
+ int ret, err, cnt;
++ struct dquot *dquot;
+
+ ret = err = 0;
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+- if (dquot[cnt])
++ dquot = srcu_dereference(dquots[cnt], &dquot_srcu);
++ if (dquot)
+ /* Even in case of error we have to continue */
+- ret = mark_dquot_dirty(dquot[cnt]);
++ ret = mark_dquot_dirty(dquot);
+ if (!err)
+ err = ret;
+ }
+@@ -1684,6 +1686,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
+ struct dquot_warn warn[MAXQUOTAS];
+ int reserve = flags & DQUOT_SPACE_RESERVE;
+ struct dquot **dquots;
++ struct dquot *dquot;
+
+ if (!inode_quota_active(inode)) {
+ if (reserve) {
+@@ -1703,27 +1706,26 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
+ index = srcu_read_lock(&dquot_srcu);
+ spin_lock(&inode->i_lock);
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+- if (!dquots[cnt])
++ dquot = srcu_dereference(dquots[cnt], &dquot_srcu);
++ if (!dquot)
+ continue;
+ if (reserve) {
+- ret = dquot_add_space(dquots[cnt], 0, number, flags,
+- &warn[cnt]);
++ ret = dquot_add_space(dquot, 0, number, flags, &warn[cnt]);
+ } else {
+- ret = dquot_add_space(dquots[cnt], number, 0, flags,
+- &warn[cnt]);
++ ret = dquot_add_space(dquot, number, 0, flags, &warn[cnt]);
+ }
+ if (ret) {
+ /* Back out changes we already did */
+ for (cnt--; cnt >= 0; cnt--) {
+- if (!dquots[cnt])
++ dquot = srcu_dereference(dquots[cnt], &dquot_srcu);
++ if (!dquot)
+ continue;
+- spin_lock(&dquots[cnt]->dq_dqb_lock);
++ spin_lock(&dquot->dq_dqb_lock);
+ if (reserve)
+- dquot_free_reserved_space(dquots[cnt],
+- number);
++ dquot_free_reserved_space(dquot, number);
+ else
+- dquot_decr_space(dquots[cnt], number);
+- spin_unlock(&dquots[cnt]->dq_dqb_lock);
++ dquot_decr_space(dquot, number);
++ spin_unlock(&dquot->dq_dqb_lock);
+ }
+ spin_unlock(&inode->i_lock);
+ goto out_flush_warn;
+@@ -1754,6 +1756,7 @@ int dquot_alloc_inode(struct inode *inode)
+ int cnt, ret = 0, index;
+ struct dquot_warn warn[MAXQUOTAS];
+ struct dquot * const *dquots;
++ struct dquot *dquot;
+
+ if (!inode_quota_active(inode))
+ return 0;
+@@ -1764,17 +1767,19 @@ int dquot_alloc_inode(struct inode *inode)
+ index = srcu_read_lock(&dquot_srcu);
+ spin_lock(&inode->i_lock);
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+- if (!dquots[cnt])
++ dquot = srcu_dereference(dquots[cnt], &dquot_srcu);
++ if (!dquot)
+ continue;
+- ret = dquot_add_inodes(dquots[cnt], 1, &warn[cnt]);
++ ret = dquot_add_inodes(dquot, 1, &warn[cnt]);
+ if (ret) {
+ for (cnt--; cnt >= 0; cnt--) {
+- if (!dquots[cnt])
++ dquot = srcu_dereference(dquots[cnt], &dquot_srcu);
++ if (!dquot)
+ continue;
+ /* Back out changes we already did */
+- spin_lock(&dquots[cnt]->dq_dqb_lock);
+- dquot_decr_inodes(dquots[cnt], 1);
+- spin_unlock(&dquots[cnt]->dq_dqb_lock);
++ spin_lock(&dquot->dq_dqb_lock);
++ dquot_decr_inodes(dquot, 1);
++ spin_unlock(&dquot->dq_dqb_lock);
+ }
+ goto warn_put_all;
+ }
+@@ -1796,6 +1801,7 @@ EXPORT_SYMBOL(dquot_alloc_inode);
+ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
+ {
+ struct dquot **dquots;
++ struct dquot *dquot;
+ int cnt, index;
+
+ if (!inode_quota_active(inode)) {
+@@ -1811,9 +1817,8 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
+ spin_lock(&inode->i_lock);
+ /* Claim reserved quotas to allocated quotas */
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+- if (dquots[cnt]) {
+- struct dquot *dquot = dquots[cnt];
+-
++ dquot = srcu_dereference(dquots[cnt], &dquot_srcu);
++ if (dquot) {
+ spin_lock(&dquot->dq_dqb_lock);
+ if (WARN_ON_ONCE(dquot->dq_dqb.dqb_rsvspace < number))
+ number = dquot->dq_dqb.dqb_rsvspace;
+@@ -1838,6 +1843,7 @@ EXPORT_SYMBOL(dquot_claim_space_nodirty);
+ void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number)
+ {
+ struct dquot **dquots;
++ struct dquot *dquot;
+ int cnt, index;
+
+ if (!inode_quota_active(inode)) {
+@@ -1853,9 +1859,8 @@ void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number)
+ spin_lock(&inode->i_lock);
+ /* Claim reserved quotas to allocated quotas */
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+- if (dquots[cnt]) {
+- struct dquot *dquot = dquots[cnt];
+-
++ dquot = srcu_dereference(dquots[cnt], &dquot_srcu);
++ if (dquot) {
+ spin_lock(&dquot->dq_dqb_lock);
+ if (WARN_ON_ONCE(dquot->dq_dqb.dqb_curspace < number))
+ number = dquot->dq_dqb.dqb_curspace;
+@@ -1882,6 +1887,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
+ unsigned int cnt;
+ struct dquot_warn warn[MAXQUOTAS];
+ struct dquot **dquots;
++ struct dquot *dquot;
+ int reserve = flags & DQUOT_SPACE_RESERVE, index;
+
+ if (!inode_quota_active(inode)) {
+@@ -1902,17 +1908,18 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
+ int wtype;
+
+ warn[cnt].w_type = QUOTA_NL_NOWARN;
+- if (!dquots[cnt])
++ dquot = srcu_dereference(dquots[cnt], &dquot_srcu);
++ if (!dquot)
+ continue;
+- spin_lock(&dquots[cnt]->dq_dqb_lock);
+- wtype = info_bdq_free(dquots[cnt], number);
++ spin_lock(&dquot->dq_dqb_lock);
++ wtype = info_bdq_free(dquot, number);
+ if (wtype != QUOTA_NL_NOWARN)
+- prepare_warning(&warn[cnt], dquots[cnt], wtype);
++ prepare_warning(&warn[cnt], dquot, wtype);
+ if (reserve)
+- dquot_free_reserved_space(dquots[cnt], number);
++ dquot_free_reserved_space(dquot, number);
+ else
+- dquot_decr_space(dquots[cnt], number);
+- spin_unlock(&dquots[cnt]->dq_dqb_lock);
++ dquot_decr_space(dquot, number);
++ spin_unlock(&dquot->dq_dqb_lock);
+ }
+ if (reserve)
+ *inode_reserved_space(inode) -= number;
+@@ -1937,6 +1944,7 @@ void dquot_free_inode(struct inode *inode)
+ unsigned int cnt;
+ struct dquot_warn warn[MAXQUOTAS];
+ struct dquot * const *dquots;
++ struct dquot *dquot;
+ int index;
+
+ if (!inode_quota_active(inode))
+@@ -1947,16 +1955,16 @@ void dquot_free_inode(struct inode *inode)
+ spin_lock(&inode->i_lock);
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+ int wtype;
+-
+ warn[cnt].w_type = QUOTA_NL_NOWARN;
+- if (!dquots[cnt])
++ dquot = srcu_dereference(dquots[cnt], &dquot_srcu);
++ if (!dquot)
+ continue;
+- spin_lock(&dquots[cnt]->dq_dqb_lock);
+- wtype = info_idq_free(dquots[cnt], 1);
++ spin_lock(&dquot->dq_dqb_lock);
++ wtype = info_idq_free(dquot, 1);
+ if (wtype != QUOTA_NL_NOWARN)
+- prepare_warning(&warn[cnt], dquots[cnt], wtype);
+- dquot_decr_inodes(dquots[cnt], 1);
+- spin_unlock(&dquots[cnt]->dq_dqb_lock);
++ prepare_warning(&warn[cnt], dquot, wtype);
++ dquot_decr_inodes(dquot, 1);
++ spin_unlock(&dquot->dq_dqb_lock);
+ }
+ spin_unlock(&inode->i_lock);
+ mark_all_dquot_dirty(dquots);
+@@ -1983,7 +1991,7 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
+ qsize_t rsv_space = 0;
+ qsize_t inode_usage = 1;
+ struct dquot *transfer_from[MAXQUOTAS] = {};
+- int cnt, ret = 0;
++ int cnt, index, ret = 0;
+ char is_valid[MAXQUOTAS] = {};
+ struct dquot_warn warn_to[MAXQUOTAS];
+ struct dquot_warn warn_from_inodes[MAXQUOTAS];
+@@ -2072,8 +2080,16 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
+ spin_unlock(&inode->i_lock);
+ spin_unlock(&dq_data_lock);
+
++ /*
++ * These arrays are local and we hold dquot references so we don't need
++ * the srcu protection but still take dquot_srcu to avoid warning in
++ * mark_all_dquot_dirty().
++ */
++ index = srcu_read_lock(&dquot_srcu);
+ mark_all_dquot_dirty(transfer_from);
+ mark_all_dquot_dirty(transfer_to);
++ srcu_read_unlock(&dquot_srcu, index);
++
+ flush_warnings(warn_to);
+ flush_warnings(warn_from_inodes);
+ flush_warnings(warn_from_space);
+--
+2.43.0
+
--- /dev/null
+From 40287aff4b5937a5c23db1e30b8522081d98e327 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Feb 2024 15:32:09 +0100
+Subject: quota: Fix rcu annotations of inode dquot pointers
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 179b8c97ebf63429589f5afeba59a181fe70603e ]
+
+Dquot pointers in i_dquot array in the inode are protected by
+dquot_srcu. Annotate the array pointers with __rcu, perform the locked
+dereferences with srcu_dereference_check() instead of plain reads, and
+set the array elements with rcu_assign_pointer().
+
+Fixes: b9ba6f94b238 ("quota: remove dqptr_sem")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202402061900.rTuYDlo6-lkp@intel.com/
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/quota/dquot.c | 66 ++++++++++++++++++++++++++++--------------------
+ 1 file changed, 39 insertions(+), 27 deletions(-)
+
+diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
+index 44c4da364c994..b67557647d61f 100644
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -399,7 +399,7 @@ int dquot_mark_dquot_dirty(struct dquot *dquot)
+ EXPORT_SYMBOL(dquot_mark_dquot_dirty);
+
+ /* Dirtify all the dquots - this can block when journalling */
+-static inline int mark_all_dquot_dirty(struct dquot * const *dquots)
++static inline int mark_all_dquot_dirty(struct dquot __rcu * const *dquots)
+ {
+ int ret, err, cnt;
+ struct dquot *dquot;
+@@ -1006,14 +1006,15 @@ struct dquot *dqget(struct super_block *sb, struct kqid qid)
+ }
+ EXPORT_SYMBOL(dqget);
+
+-static inline struct dquot **i_dquot(struct inode *inode)
++static inline struct dquot __rcu **i_dquot(struct inode *inode)
+ {
+- return inode->i_sb->s_op->get_dquots(inode);
++ /* Force __rcu for now until filesystems are fixed */
++ return (struct dquot __rcu **)inode->i_sb->s_op->get_dquots(inode);
+ }
+
+ static int dqinit_needed(struct inode *inode, int type)
+ {
+- struct dquot * const *dquots;
++ struct dquot __rcu * const *dquots;
+ int cnt;
+
+ if (IS_NOQUOTA(inode))
+@@ -1103,14 +1104,16 @@ static void remove_dquot_ref(struct super_block *sb, int type)
+ */
+ spin_lock(&dq_data_lock);
+ if (!IS_NOQUOTA(inode)) {
+- struct dquot **dquots = i_dquot(inode);
+- struct dquot *dquot = dquots[type];
++ struct dquot __rcu **dquots = i_dquot(inode);
++ struct dquot *dquot = srcu_dereference_check(
++ dquots[type], &dquot_srcu,
++ lockdep_is_held(&dq_data_lock));
+
+ #ifdef CONFIG_QUOTA_DEBUG
+ if (unlikely(inode_get_rsv_space(inode) > 0))
+ reserved = 1;
+ #endif
+- dquots[type] = NULL;
++ rcu_assign_pointer(dquots[type], NULL);
+ if (dquot)
+ dqput(dquot);
+ }
+@@ -1463,7 +1466,8 @@ static int inode_quota_active(const struct inode *inode)
+ static int __dquot_initialize(struct inode *inode, int type)
+ {
+ int cnt, init_needed = 0;
+- struct dquot **dquots, *got[MAXQUOTAS] = {};
++ struct dquot __rcu **dquots;
++ struct dquot *got[MAXQUOTAS] = {};
+ struct super_block *sb = inode->i_sb;
+ qsize_t rsv;
+ int ret = 0;
+@@ -1538,7 +1542,7 @@ static int __dquot_initialize(struct inode *inode, int type)
+ if (!got[cnt])
+ continue;
+ if (!dquots[cnt]) {
+- dquots[cnt] = got[cnt];
++ rcu_assign_pointer(dquots[cnt], got[cnt]);
+ got[cnt] = NULL;
+ /*
+ * Make quota reservation system happy if someone
+@@ -1546,12 +1550,16 @@ static int __dquot_initialize(struct inode *inode, int type)
+ */
+ rsv = inode_get_rsv_space(inode);
+ if (unlikely(rsv)) {
++ struct dquot *dquot = srcu_dereference_check(
++ dquots[cnt], &dquot_srcu,
++ lockdep_is_held(&dq_data_lock));
++
+ spin_lock(&inode->i_lock);
+ /* Get reservation again under proper lock */
+ rsv = __inode_get_rsv_space(inode);
+- spin_lock(&dquots[cnt]->dq_dqb_lock);
+- dquots[cnt]->dq_dqb.dqb_rsvspace += rsv;
+- spin_unlock(&dquots[cnt]->dq_dqb_lock);
++ spin_lock(&dquot->dq_dqb_lock);
++ dquot->dq_dqb.dqb_rsvspace += rsv;
++ spin_unlock(&dquot->dq_dqb_lock);
+ spin_unlock(&inode->i_lock);
+ }
+ }
+@@ -1573,7 +1581,7 @@ EXPORT_SYMBOL(dquot_initialize);
+
+ bool dquot_initialize_needed(struct inode *inode)
+ {
+- struct dquot **dquots;
++ struct dquot __rcu **dquots;
+ int i;
+
+ if (!inode_quota_active(inode))
+@@ -1598,13 +1606,14 @@ EXPORT_SYMBOL(dquot_initialize_needed);
+ static void __dquot_drop(struct inode *inode)
+ {
+ int cnt;
+- struct dquot **dquots = i_dquot(inode);
++ struct dquot __rcu **dquots = i_dquot(inode);
+ struct dquot *put[MAXQUOTAS];
+
+ spin_lock(&dq_data_lock);
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+- put[cnt] = dquots[cnt];
+- dquots[cnt] = NULL;
++ put[cnt] = srcu_dereference_check(dquots[cnt], &dquot_srcu,
++ lockdep_is_held(&dq_data_lock));
++ rcu_assign_pointer(dquots[cnt], NULL);
+ }
+ spin_unlock(&dq_data_lock);
+ dqput_all(put);
+@@ -1612,7 +1621,7 @@ static void __dquot_drop(struct inode *inode)
+
+ void dquot_drop(struct inode *inode)
+ {
+- struct dquot * const *dquots;
++ struct dquot __rcu * const *dquots;
+ int cnt;
+
+ if (IS_NOQUOTA(inode))
+@@ -1685,7 +1694,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
+ int cnt, ret = 0, index;
+ struct dquot_warn warn[MAXQUOTAS];
+ int reserve = flags & DQUOT_SPACE_RESERVE;
+- struct dquot **dquots;
++ struct dquot __rcu **dquots;
+ struct dquot *dquot;
+
+ if (!inode_quota_active(inode)) {
+@@ -1755,7 +1764,7 @@ int dquot_alloc_inode(struct inode *inode)
+ {
+ int cnt, ret = 0, index;
+ struct dquot_warn warn[MAXQUOTAS];
+- struct dquot * const *dquots;
++ struct dquot __rcu * const *dquots;
+ struct dquot *dquot;
+
+ if (!inode_quota_active(inode))
+@@ -1800,7 +1809,7 @@ EXPORT_SYMBOL(dquot_alloc_inode);
+ */
+ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
+ {
+- struct dquot **dquots;
++ struct dquot __rcu **dquots;
+ struct dquot *dquot;
+ int cnt, index;
+
+@@ -1842,7 +1851,7 @@ EXPORT_SYMBOL(dquot_claim_space_nodirty);
+ */
+ void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number)
+ {
+- struct dquot **dquots;
++ struct dquot __rcu **dquots;
+ struct dquot *dquot;
+ int cnt, index;
+
+@@ -1886,7 +1895,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
+ {
+ unsigned int cnt;
+ struct dquot_warn warn[MAXQUOTAS];
+- struct dquot **dquots;
++ struct dquot __rcu **dquots;
+ struct dquot *dquot;
+ int reserve = flags & DQUOT_SPACE_RESERVE, index;
+
+@@ -1943,7 +1952,7 @@ void dquot_free_inode(struct inode *inode)
+ {
+ unsigned int cnt;
+ struct dquot_warn warn[MAXQUOTAS];
+- struct dquot * const *dquots;
++ struct dquot __rcu * const *dquots;
+ struct dquot *dquot;
+ int index;
+
+@@ -1990,6 +1999,7 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
+ qsize_t cur_space;
+ qsize_t rsv_space = 0;
+ qsize_t inode_usage = 1;
++ struct dquot __rcu **dquots;
+ struct dquot *transfer_from[MAXQUOTAS] = {};
+ int cnt, index, ret = 0;
+ char is_valid[MAXQUOTAS] = {};
+@@ -2022,6 +2032,7 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
+ }
+ cur_space = __inode_get_bytes(inode);
+ rsv_space = __inode_get_rsv_space(inode);
++ dquots = i_dquot(inode);
+ /*
+ * Build the transfer_from list, check limits, and update usage in
+ * the target structures.
+@@ -2036,7 +2047,8 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
+ if (!sb_has_quota_active(inode->i_sb, cnt))
+ continue;
+ is_valid[cnt] = 1;
+- transfer_from[cnt] = i_dquot(inode)[cnt];
++ transfer_from[cnt] = srcu_dereference_check(dquots[cnt],
++ &dquot_srcu, lockdep_is_held(&dq_data_lock));
+ ret = dquot_add_inodes(transfer_to[cnt], inode_usage,
+ &warn_to[cnt]);
+ if (ret)
+@@ -2075,7 +2087,7 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
+ rsv_space);
+ spin_unlock(&transfer_from[cnt]->dq_dqb_lock);
+ }
+- i_dquot(inode)[cnt] = transfer_to[cnt];
++ rcu_assign_pointer(dquots[cnt], transfer_to[cnt]);
+ }
+ spin_unlock(&inode->i_lock);
+ spin_unlock(&dq_data_lock);
+@@ -2086,8 +2098,8 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
+ * mark_all_dquot_dirty().
+ */
+ index = srcu_read_lock(&dquot_srcu);
+- mark_all_dquot_dirty(transfer_from);
+- mark_all_dquot_dirty(transfer_to);
++ mark_all_dquot_dirty((struct dquot __rcu **)transfer_from);
++ mark_all_dquot_dirty((struct dquot __rcu **)transfer_to);
+ srcu_read_unlock(&dquot_srcu, index);
+
+ flush_warnings(warn_to);
+--
+2.43.0
+
--- /dev/null
+From 53a3889cf678921b26ccc04ed4e9569ff3414263 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jun 2023 19:08:22 +0800
+Subject: quota: simplify drop_dquot_ref()
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit 7bce48f0fec602b3b6c335963b26d9eefa417788 ]
+
+As Honza said, remove_inode_dquot_ref() currently does not release the
+last dquot reference but instead adds the dquot to tofree_head list. This
+is because dqput() can sleep while dropping of the last dquot reference
+(writing back the dquot and calling ->release_dquot()) and that must not
+happen under dq_list_lock. Now that dqput() queues the final dquot cleanup
+into a workqueue, remove_inode_dquot_ref() can call dqput() unconditionally
+and we can significantly simplify it.
+
+Here we open code the simplified code of remove_inode_dquot_ref() into
+remove_dquot_ref() and remove the function put_dquot_list() which is no
+longer used.
+
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Message-Id: <20230630110822.3881712-6-libaokun1@huawei.com>
+Stable-dep-of: 179b8c97ebf6 ("quota: Fix rcu annotations of inode dquot pointers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/quota/dquot.c | 70 +++++++-----------------------------------------
+ 1 file changed, 9 insertions(+), 61 deletions(-)
+
+diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
+index b0cf3869d3bf5..730d8ffc4928a 100644
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -1084,59 +1084,7 @@ static int add_dquot_ref(struct super_block *sb, int type)
+ return err;
+ }
+
+-/*
+- * Remove references to dquots from inode and add dquot to list for freeing
+- * if we have the last reference to dquot
+- */
+-static void remove_inode_dquot_ref(struct inode *inode, int type,
+- struct list_head *tofree_head)
+-{
+- struct dquot **dquots = i_dquot(inode);
+- struct dquot *dquot = dquots[type];
+-
+- if (!dquot)
+- return;
+-
+- dquots[type] = NULL;
+- if (list_empty(&dquot->dq_free)) {
+- /*
+- * The inode still has reference to dquot so it can't be in the
+- * free list
+- */
+- spin_lock(&dq_list_lock);
+- list_add(&dquot->dq_free, tofree_head);
+- spin_unlock(&dq_list_lock);
+- } else {
+- /*
+- * Dquot is already in a list to put so we won't drop the last
+- * reference here.
+- */
+- dqput(dquot);
+- }
+-}
+-
+-/*
+- * Free list of dquots
+- * Dquots are removed from inodes and no new references can be got so we are
+- * the only ones holding reference
+- */
+-static void put_dquot_list(struct list_head *tofree_head)
+-{
+- struct list_head *act_head;
+- struct dquot *dquot;
+-
+- act_head = tofree_head->next;
+- while (act_head != tofree_head) {
+- dquot = list_entry(act_head, struct dquot, dq_free);
+- act_head = act_head->next;
+- /* Remove dquot from the list so we won't have problems... */
+- list_del_init(&dquot->dq_free);
+- dqput(dquot);
+- }
+-}
+-
+-static void remove_dquot_ref(struct super_block *sb, int type,
+- struct list_head *tofree_head)
++static void remove_dquot_ref(struct super_block *sb, int type)
+ {
+ struct inode *inode;
+ #ifdef CONFIG_QUOTA_DEBUG
+@@ -1153,11 +1101,16 @@ static void remove_dquot_ref(struct super_block *sb, int type,
+ */
+ spin_lock(&dq_data_lock);
+ if (!IS_NOQUOTA(inode)) {
++ struct dquot **dquots = i_dquot(inode);
++ struct dquot *dquot = dquots[type];
++
+ #ifdef CONFIG_QUOTA_DEBUG
+ if (unlikely(inode_get_rsv_space(inode) > 0))
+ reserved = 1;
+ #endif
+- remove_inode_dquot_ref(inode, type, tofree_head);
++ dquots[type] = NULL;
++ if (dquot)
++ dqput(dquot);
+ }
+ spin_unlock(&dq_data_lock);
+ }
+@@ -1174,13 +1127,8 @@ static void remove_dquot_ref(struct super_block *sb, int type,
+ /* Gather all references from inodes and drop them */
+ static void drop_dquot_ref(struct super_block *sb, int type)
+ {
+- LIST_HEAD(tofree_head);
+-
+- if (sb->dq_op) {
+- remove_dquot_ref(sb, type, &tofree_head);
+- synchronize_srcu(&dquot_srcu);
+- put_dquot_list(&tofree_head);
+- }
++ if (sb->dq_op)
++ remove_dquot_ref(sb, type);
+ }
+
+ static inline
+--
+2.43.0
+
--- /dev/null
+From 0f0a7e8b95480d4e319dbe04c6be0cf92239f389 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jan 2024 16:46:15 +0100
+Subject: rcu/exp: Fix RCU expedited parallel grace period kworker allocation
+ failure recovery
+
+From: Frederic Weisbecker <frederic@kernel.org>
+
+[ Upstream commit a636c5e6f8fc34be520277e69c7c6ee1d4fc1d17 ]
+
+Under CONFIG_RCU_EXP_KTHREAD=y, the nodes initialization for expedited
+grace periods is queued to a kworker. However if the allocation of that
+kworker failed, the nodes initialization is performed synchronously by
+the caller instead.
+
+Now the check for kworker initialization failure relies on the kworker
+pointer to be NULL while its value might actually encapsulate an
+allocation failure error.
+
+Make sure to handle this case.
+
+Reviewed-by: Kalesh Singh <kaleshsingh@google.com>
+Fixes: 9621fbee44df ("rcu: Move expedited grace period (GP) work to RT kthread_worker")
+Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
+Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/tree.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index 9d7464a90f85d..c879ed0c55079 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -4471,6 +4471,7 @@ static void __init rcu_start_exp_gp_kworkers(void)
+ rcu_exp_par_gp_kworker = kthread_create_worker(0, par_gp_kworker_name);
+ if (IS_ERR_OR_NULL(rcu_exp_par_gp_kworker)) {
+ pr_err("Failed to create %s!\n", par_gp_kworker_name);
++ rcu_exp_par_gp_kworker = NULL;
+ kthread_destroy_worker(rcu_exp_gp_kworker);
+ return;
+ }
+--
+2.43.0
+
--- /dev/null
+From 498ac8a91e91dbd7b68cea46f4b43f4425d7543e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jan 2024 16:46:16 +0100
+Subject: rcu/exp: Handle RCU expedited grace period kworker allocation failure
+
+From: Frederic Weisbecker <frederic@kernel.org>
+
+[ Upstream commit e7539ffc9a770f36bacedcf0fbfb4bf2f244f4a5 ]
+
+Just like is done for the kworker performing nodes initialization,
+gracefully handle the possible allocation failure of the RCU expedited
+grace period main kworker.
+
+While at it perform a rename of the related checking functions to better
+reflect the expedited specifics.
+
+Reviewed-by: Kalesh Singh <kaleshsingh@google.com>
+Fixes: 9621fbee44df ("rcu: Move expedited grace period (GP) work to RT kthread_worker")
+Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
+Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/tree.c | 2 ++
+ kernel/rcu/tree_exp.h | 25 +++++++++++++++++++------
+ 2 files changed, 21 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index c879ed0c55079..61f9503a5fe9c 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -4465,6 +4465,7 @@ static void __init rcu_start_exp_gp_kworkers(void)
+ rcu_exp_gp_kworker = kthread_create_worker(0, gp_kworker_name);
+ if (IS_ERR_OR_NULL(rcu_exp_gp_kworker)) {
+ pr_err("Failed to create %s!\n", gp_kworker_name);
++ rcu_exp_gp_kworker = NULL;
+ return;
+ }
+
+@@ -4473,6 +4474,7 @@ static void __init rcu_start_exp_gp_kworkers(void)
+ pr_err("Failed to create %s!\n", par_gp_kworker_name);
+ rcu_exp_par_gp_kworker = NULL;
+ kthread_destroy_worker(rcu_exp_gp_kworker);
++ rcu_exp_gp_kworker = NULL;
+ return;
+ }
+
+diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h
+index 6d2cbed96b462..75e8d9652f7bb 100644
+--- a/kernel/rcu/tree_exp.h
++++ b/kernel/rcu/tree_exp.h
+@@ -427,7 +427,12 @@ static void sync_rcu_exp_select_node_cpus(struct kthread_work *wp)
+ __sync_rcu_exp_select_node_cpus(rewp);
+ }
+
+-static inline bool rcu_gp_par_worker_started(void)
++static inline bool rcu_exp_worker_started(void)
++{
++ return !!READ_ONCE(rcu_exp_gp_kworker);
++}
++
++static inline bool rcu_exp_par_worker_started(void)
+ {
+ return !!READ_ONCE(rcu_exp_par_gp_kworker);
+ }
+@@ -477,7 +482,12 @@ static void sync_rcu_exp_select_node_cpus(struct work_struct *wp)
+ __sync_rcu_exp_select_node_cpus(rewp);
+ }
+
+-static inline bool rcu_gp_par_worker_started(void)
++static inline bool rcu_exp_worker_started(void)
++{
++ return !!READ_ONCE(rcu_gp_wq);
++}
++
++static inline bool rcu_exp_par_worker_started(void)
+ {
+ return !!READ_ONCE(rcu_par_gp_wq);
+ }
+@@ -540,7 +550,7 @@ static void sync_rcu_exp_select_cpus(void)
+ rnp->exp_need_flush = false;
+ if (!READ_ONCE(rnp->expmask))
+ continue; /* Avoid early boot non-existent wq. */
+- if (!rcu_gp_par_worker_started() ||
++ if (!rcu_exp_par_worker_started() ||
+ rcu_scheduler_active != RCU_SCHEDULER_RUNNING ||
+ rcu_is_last_leaf_node(rnp)) {
+ /* No worker started yet or last leaf, do direct call. */
+@@ -910,7 +920,7 @@ static int rcu_print_task_exp_stall(struct rcu_node *rnp)
+ */
+ void synchronize_rcu_expedited(void)
+ {
+- bool boottime = (rcu_scheduler_active == RCU_SCHEDULER_INIT);
++ bool use_worker;
+ unsigned long flags;
+ struct rcu_exp_work rew;
+ struct rcu_node *rnp;
+@@ -921,6 +931,9 @@ void synchronize_rcu_expedited(void)
+ lock_is_held(&rcu_sched_lock_map),
+ "Illegal synchronize_rcu_expedited() in RCU read-side critical section");
+
++ use_worker = (rcu_scheduler_active != RCU_SCHEDULER_INIT) &&
++ rcu_exp_worker_started();
++
+ /* Is the state is such that the call is a grace period? */
+ if (rcu_blocking_is_gp()) {
+ // Note well that this code runs with !PREEMPT && !SMP.
+@@ -950,7 +963,7 @@ void synchronize_rcu_expedited(void)
+ return; /* Someone else did our work for us. */
+
+ /* Ensure that load happens before action based on it. */
+- if (unlikely(boottime)) {
++ if (unlikely(!use_worker)) {
+ /* Direct call during scheduler init and early_initcalls(). */
+ rcu_exp_sel_wait_wake(s);
+ } else {
+@@ -968,7 +981,7 @@ void synchronize_rcu_expedited(void)
+ /* Let the next expedited grace period start. */
+ mutex_unlock(&rcu_state.exp_mutex);
+
+- if (likely(!boottime))
++ if (likely(use_worker))
+ synchronize_rcu_expedited_destroy_work(&rew);
+ }
+ EXPORT_SYMBOL_GPL(synchronize_rcu_expedited);
+--
+2.43.0
+
--- /dev/null
+From 84913afd735c5495ef6b8df7bc41b4806b1d8de5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Feb 2024 19:53:13 -0800
+Subject: RDMA/device: Fix a race between mad_client and cm_client init
+
+From: Shifeng Li <lishifeng@sangfor.com.cn>
+
+[ Upstream commit 7a8bccd8b29c321ac181369b42b04fecf05f98e2 ]
+
+The mad_client will be initialized in enable_device_and_get(), while the
+devices_rwsem will be downgraded to a read semaphore. There is a window
+that leads to the failed initialization for cm_client, since it can not
+get matched mad port from ib_mad_port_list, and the matched mad port will
+be added to the list after that.
+
+ mad_client | cm_client
+------------------|--------------------------------------------------------
+ib_register_device|
+enable_device_and_get
+down_write(&devices_rwsem)
+xa_set_mark(&devices, DEVICE_REGISTERED)
+downgrade_write(&devices_rwsem)
+ |
+ |ib_cm_init
+ |ib_register_client(&cm_client)
+ |down_read(&devices_rwsem)
+ |xa_for_each_marked (&devices, DEVICE_REGISTERED)
+ |add_client_context
+ |cm_add_one
+ |ib_register_mad_agent
+ |ib_get_mad_port
+ |__ib_get_mad_port
+ |list_for_each_entry(entry, &ib_mad_port_list, port_list)
+ |return NULL
+ |up_read(&devices_rwsem)
+ |
+add_client_context|
+ib_mad_init_device|
+ib_mad_port_open |
+list_add_tail(&port_priv->port_list, &ib_mad_port_list)
+up_read(&devices_rwsem)
+ |
+
+Fix it by using down_write(&devices_rwsem) in ib_register_client().
+
+Fixes: d0899892edd0 ("RDMA/device: Provide APIs from the core code to help unregistration")
+Link: https://lore.kernel.org/r/20240203035313.98991-1-lishifeng@sangfor.com.cn
+Suggested-by: Jason Gunthorpe <jgg@ziepe.ca>
+Signed-off-by: Shifeng Li <lishifeng@sangfor.com.cn>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/device.c | 37 +++++++++++++++++++-------------
+ 1 file changed, 22 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
+index 3a9b9a28d858f..453188db39d83 100644
+--- a/drivers/infiniband/core/device.c
++++ b/drivers/infiniband/core/device.c
+@@ -1730,7 +1730,7 @@ static int assign_client_id(struct ib_client *client)
+ {
+ int ret;
+
+- down_write(&clients_rwsem);
++ lockdep_assert_held(&clients_rwsem);
+ /*
+ * The add/remove callbacks must be called in FIFO/LIFO order. To
+ * achieve this we assign client_ids so they are sorted in
+@@ -1739,14 +1739,11 @@ static int assign_client_id(struct ib_client *client)
+ client->client_id = highest_client_id;
+ ret = xa_insert(&clients, client->client_id, client, GFP_KERNEL);
+ if (ret)
+- goto out;
++ return ret;
+
+ highest_client_id++;
+ xa_set_mark(&clients, client->client_id, CLIENT_REGISTERED);
+-
+-out:
+- up_write(&clients_rwsem);
+- return ret;
++ return 0;
+ }
+
+ static void remove_client_id(struct ib_client *client)
+@@ -1776,25 +1773,35 @@ int ib_register_client(struct ib_client *client)
+ {
+ struct ib_device *device;
+ unsigned long index;
++ bool need_unreg = false;
+ int ret;
+
+ refcount_set(&client->uses, 1);
+ init_completion(&client->uses_zero);
++
++ /*
++ * The devices_rwsem is held in write mode to ensure that a racing
++ * ib_register_device() sees a consisent view of clients and devices.
++ */
++ down_write(&devices_rwsem);
++ down_write(&clients_rwsem);
+ ret = assign_client_id(client);
+ if (ret)
+- return ret;
++ goto out;
+
+- down_read(&devices_rwsem);
++ need_unreg = true;
+ xa_for_each_marked (&devices, index, device, DEVICE_REGISTERED) {
+ ret = add_client_context(device, client);
+- if (ret) {
+- up_read(&devices_rwsem);
+- ib_unregister_client(client);
+- return ret;
+- }
++ if (ret)
++ goto out;
+ }
+- up_read(&devices_rwsem);
+- return 0;
++ ret = 0;
++out:
++ up_write(&clients_rwsem);
++ up_write(&devices_rwsem);
++ if (need_unreg && ret)
++ ib_unregister_client(client);
++ return ret;
+ }
+ EXPORT_SYMBOL(ib_register_client);
+
+--
+2.43.0
+
--- /dev/null
+From 3c6c13a9c346ed24ea84b40cc72795d88d86546e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Feb 2024 14:18:05 +0800
+Subject: RDMA/hns: Fix mis-modifying default congestion control algorithm
+
+From: Luoyouming <luoyouming@huawei.com>
+
+[ Upstream commit d20a7cf9f714f0763efb56f0f2eeca1cb91315ed ]
+
+Commit 27c5fd271d8b ("RDMA/hns: The UD mode can only be configured
+with DCQCN") adds a check of congest control alorithm for UD. But
+that patch causes a problem: hr_dev->caps.congest_type is global,
+used by all QPs, so modifying this field to DCQCN for UD QPs causes
+other QPs unable to use any other algorithm except DCQCN.
+
+Revert the modification in commit 27c5fd271d8b ("RDMA/hns: The UD
+mode can only be configured with DCQCN"). Add a new field cong_type
+to struct hns_roce_qp and configure DCQCN for UD QPs.
+
+Fixes: 27c5fd271d8b ("RDMA/hns: The UD mode can only be configured with DCQCN")
+Fixes: f91696f2f053 ("RDMA/hns: Support congestion control type selection according to the FW")
+Signed-off-by: Luoyouming <luoyouming@huawei.com>
+Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Link: https://lore.kernel.org/r/20240219061805.668170-1-huangjunxian6@hisilicon.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_device.h | 17 +++++++++--------
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 16 ++++++++++------
+ 2 files changed, 19 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h
+index 1112afa0af552..8748b65c87ea7 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_device.h
++++ b/drivers/infiniband/hw/hns/hns_roce_device.h
+@@ -595,6 +595,13 @@ struct hns_roce_work {
+ u32 queue_num;
+ };
+
++enum hns_roce_cong_type {
++ CONG_TYPE_DCQCN,
++ CONG_TYPE_LDCP,
++ CONG_TYPE_HC3,
++ CONG_TYPE_DIP,
++};
++
+ struct hns_roce_qp {
+ struct ib_qp ibqp;
+ struct hns_roce_wq rq;
+@@ -639,6 +646,7 @@ struct hns_roce_qp {
+ struct list_head sq_node; /* all send qps are on a list */
+ struct hns_user_mmap_entry *dwqe_mmap_entry;
+ u32 config;
++ enum hns_roce_cong_type cong_type;
+ };
+
+ struct hns_roce_ib_iboe {
+@@ -710,13 +718,6 @@ struct hns_roce_eq_table {
+ struct hns_roce_eq *eq;
+ };
+
+-enum cong_type {
+- CONG_TYPE_DCQCN,
+- CONG_TYPE_LDCP,
+- CONG_TYPE_HC3,
+- CONG_TYPE_DIP,
+-};
+-
+ struct hns_roce_caps {
+ u64 fw_ver;
+ u8 num_ports;
+@@ -847,7 +848,7 @@ struct hns_roce_caps {
+ u16 default_aeq_period;
+ u16 default_aeq_arm_st;
+ u16 default_ceq_arm_st;
+- enum cong_type cong_type;
++ enum hns_roce_cong_type cong_type;
+ };
+
+ enum hns_roce_device_state {
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 58fbb1d3b7f41..d06b19e69a151 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -4886,12 +4886,15 @@ static int check_cong_type(struct ib_qp *ibqp,
+ struct hns_roce_congestion_algorithm *cong_alg)
+ {
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
++ struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
+
+- if (ibqp->qp_type == IB_QPT_UD)
+- hr_dev->caps.cong_type = CONG_TYPE_DCQCN;
++ if (ibqp->qp_type == IB_QPT_UD || ibqp->qp_type == IB_QPT_GSI)
++ hr_qp->cong_type = CONG_TYPE_DCQCN;
++ else
++ hr_qp->cong_type = hr_dev->caps.cong_type;
+
+ /* different congestion types match different configurations */
+- switch (hr_dev->caps.cong_type) {
++ switch (hr_qp->cong_type) {
+ case CONG_TYPE_DCQCN:
+ cong_alg->alg_sel = CONG_DCQCN;
+ cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL;
+@@ -4919,8 +4922,8 @@ static int check_cong_type(struct ib_qp *ibqp,
+ default:
+ ibdev_warn(&hr_dev->ib_dev,
+ "invalid type(%u) for congestion selection.\n",
+- hr_dev->caps.cong_type);
+- hr_dev->caps.cong_type = CONG_TYPE_DCQCN;
++ hr_qp->cong_type);
++ hr_qp->cong_type = CONG_TYPE_DCQCN;
+ cong_alg->alg_sel = CONG_DCQCN;
+ cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL;
+ cong_alg->dip_vld = DIP_INVALID;
+@@ -4939,6 +4942,7 @@ static int fill_cong_field(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
+ struct hns_roce_congestion_algorithm cong_field;
+ struct ib_device *ibdev = ibqp->device;
+ struct hns_roce_dev *hr_dev = to_hr_dev(ibdev);
++ struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
+ u32 dip_idx = 0;
+ int ret;
+
+@@ -4951,7 +4955,7 @@ static int fill_cong_field(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
+ return ret;
+
+ hr_reg_write(context, QPC_CONG_ALGO_TMPL_ID, hr_dev->cong_algo_tmpl_id +
+- hr_dev->caps.cong_type * HNS_ROCE_CONG_SIZE);
++ hr_qp->cong_type * HNS_ROCE_CONG_SIZE);
+ hr_reg_clear(qpc_mask, QPC_CONG_ALGO_TMPL_ID);
+ hr_reg_write(&context->ext, QPCEX_CONG_ALG_SEL, cong_field.alg_sel);
+ hr_reg_clear(&qpc_mask->ext, QPCEX_CONG_ALG_SEL);
+--
+2.43.0
+
--- /dev/null
+From 112a60abf5e036a300aa48ea17d8b4a6c66e8fc7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 10:55:24 -0500
+Subject: RDMA/irdma: Allow accurate reporting on QP max send/recv WR
+
+From: Sindhu Devale <sindhu.devale@intel.com>
+
+[ Upstream commit 3a8498720450174b8db450d3375a04dca81b3534 ]
+
+Currently the attribute cap.max_send_wr and cap.max_recv_wr
+sent from user-space during create QP are the provider computed
+SQ/RQ depth as opposed to raw values passed from application.
+This inhibits computation of an accurate value for max_send_wr
+and max_recv_wr for this QP in the kernel which matches the value
+returned in user create QP. Also these capabilities needs to be
+reported from the driver in query QP.
+
+Add support by extending the ABI to allow the raw cap.max_send_wr and
+cap.max_recv_wr to be passed from user-space, while keeping compatibility
+for the older scheme.
+
+The internal HW depth and shift needed for the WQs needs to be computed
+now for both kernel and user-mode QPs. Add new helpers to assist with this:
+irdma_uk_calc_depth_shift_sq, irdma_uk_calc_depth_shift_rq and
+irdma_uk_calc_depth_shift_wq.
+
+Consolidate all the user mode QP setup into a new function
+irdma_setup_umode_qp which keeps it with its counterpart
+irdma_setup_kmode_qp.
+
+Signed-off-by: Youvaraj Sagar <youvaraj.sagar@intel.com>
+Signed-off-by: Sindhu Devale <sindhu.devale@intel.com>
+Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Link: https://lore.kernel.org/r/20230725155525.1081-2-shiraz.saleem@intel.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: 926e8ea4b8da ("RDMA/irdma: Remove duplicate assignment")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/uk.c | 89 +++++++++++---
+ drivers/infiniband/hw/irdma/user.h | 10 ++
+ drivers/infiniband/hw/irdma/verbs.c | 182 +++++++++++++++++-----------
+ drivers/infiniband/hw/irdma/verbs.h | 3 +-
+ include/uapi/rdma/irdma-abi.h | 6 +
+ 5 files changed, 203 insertions(+), 87 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/uk.c b/drivers/infiniband/hw/irdma/uk.c
+index 280d633d4ec4f..d691cdef5e9a3 100644
+--- a/drivers/infiniband/hw/irdma/uk.c
++++ b/drivers/infiniband/hw/irdma/uk.c
+@@ -1414,6 +1414,78 @@ static void irdma_setup_connection_wqes(struct irdma_qp_uk *qp,
+ IRDMA_RING_MOVE_HEAD_BY_COUNT_NOCHECK(qp->initial_ring, move_cnt);
+ }
+
++/**
++ * irdma_uk_calc_shift_wq - calculate WQE shift for both SQ and RQ
++ * @ukinfo: qp initialization info
++ * @sq_shift: Returns shift of SQ
++ * @rq_shift: Returns shift of RQ
++ */
++void irdma_uk_calc_shift_wq(struct irdma_qp_uk_init_info *ukinfo, u8 *sq_shift,
++ u8 *rq_shift)
++{
++ bool imm_support = ukinfo->uk_attrs->hw_rev >= IRDMA_GEN_2;
++
++ irdma_get_wqe_shift(ukinfo->uk_attrs,
++ imm_support ? ukinfo->max_sq_frag_cnt + 1 :
++ ukinfo->max_sq_frag_cnt,
++ ukinfo->max_inline_data, sq_shift);
++
++ irdma_get_wqe_shift(ukinfo->uk_attrs, ukinfo->max_rq_frag_cnt, 0,
++ rq_shift);
++
++ if (ukinfo->uk_attrs->hw_rev == IRDMA_GEN_1) {
++ if (ukinfo->abi_ver > 4)
++ *rq_shift = IRDMA_MAX_RQ_WQE_SHIFT_GEN1;
++ }
++}
++
++/**
++ * irdma_uk_calc_depth_shift_sq - calculate depth and shift for SQ size.
++ * @ukinfo: qp initialization info
++ * @sq_depth: Returns depth of SQ
++ * @sq_shift: Returns shift of SQ
++ */
++int irdma_uk_calc_depth_shift_sq(struct irdma_qp_uk_init_info *ukinfo,
++ u32 *sq_depth, u8 *sq_shift)
++{
++ bool imm_support = ukinfo->uk_attrs->hw_rev >= IRDMA_GEN_2;
++ int status;
++
++ irdma_get_wqe_shift(ukinfo->uk_attrs,
++ imm_support ? ukinfo->max_sq_frag_cnt + 1 :
++ ukinfo->max_sq_frag_cnt,
++ ukinfo->max_inline_data, sq_shift);
++ status = irdma_get_sqdepth(ukinfo->uk_attrs, ukinfo->sq_size,
++ *sq_shift, sq_depth);
++
++ return status;
++}
++
++/**
++ * irdma_uk_calc_depth_shift_rq - calculate depth and shift for RQ size.
++ * @ukinfo: qp initialization info
++ * @rq_depth: Returns depth of RQ
++ * @rq_shift: Returns shift of RQ
++ */
++int irdma_uk_calc_depth_shift_rq(struct irdma_qp_uk_init_info *ukinfo,
++ u32 *rq_depth, u8 *rq_shift)
++{
++ int status;
++
++ irdma_get_wqe_shift(ukinfo->uk_attrs, ukinfo->max_rq_frag_cnt, 0,
++ rq_shift);
++
++ if (ukinfo->uk_attrs->hw_rev == IRDMA_GEN_1) {
++ if (ukinfo->abi_ver > 4)
++ *rq_shift = IRDMA_MAX_RQ_WQE_SHIFT_GEN1;
++ }
++
++ status = irdma_get_rqdepth(ukinfo->uk_attrs, ukinfo->rq_size,
++ *rq_shift, rq_depth);
++
++ return status;
++}
++
+ /**
+ * irdma_uk_qp_init - initialize shared qp
+ * @qp: hw qp (user and kernel)
+@@ -1428,23 +1500,12 @@ int irdma_uk_qp_init(struct irdma_qp_uk *qp, struct irdma_qp_uk_init_info *info)
+ {
+ int ret_code = 0;
+ u32 sq_ring_size;
+- u8 sqshift, rqshift;
+
+ qp->uk_attrs = info->uk_attrs;
+ if (info->max_sq_frag_cnt > qp->uk_attrs->max_hw_wq_frags ||
+ info->max_rq_frag_cnt > qp->uk_attrs->max_hw_wq_frags)
+ return -EINVAL;
+
+- irdma_get_wqe_shift(qp->uk_attrs, info->max_rq_frag_cnt, 0, &rqshift);
+- if (qp->uk_attrs->hw_rev == IRDMA_GEN_1) {
+- irdma_get_wqe_shift(qp->uk_attrs, info->max_sq_frag_cnt,
+- info->max_inline_data, &sqshift);
+- if (info->abi_ver > 4)
+- rqshift = IRDMA_MAX_RQ_WQE_SHIFT_GEN1;
+- } else {
+- irdma_get_wqe_shift(qp->uk_attrs, info->max_sq_frag_cnt + 1,
+- info->max_inline_data, &sqshift);
+- }
+ qp->qp_caps = info->qp_caps;
+ qp->sq_base = info->sq;
+ qp->rq_base = info->rq;
+@@ -1458,7 +1519,7 @@ int irdma_uk_qp_init(struct irdma_qp_uk *qp, struct irdma_qp_uk_init_info *info)
+ qp->sq_size = info->sq_size;
+ qp->push_mode = false;
+ qp->max_sq_frag_cnt = info->max_sq_frag_cnt;
+- sq_ring_size = qp->sq_size << sqshift;
++ sq_ring_size = qp->sq_size << info->sq_shift;
+ IRDMA_RING_INIT(qp->sq_ring, sq_ring_size);
+ IRDMA_RING_INIT(qp->initial_ring, sq_ring_size);
+ if (info->first_sq_wq) {
+@@ -1473,9 +1534,9 @@ int irdma_uk_qp_init(struct irdma_qp_uk *qp, struct irdma_qp_uk_init_info *info)
+ qp->rq_size = info->rq_size;
+ qp->max_rq_frag_cnt = info->max_rq_frag_cnt;
+ qp->max_inline_data = info->max_inline_data;
+- qp->rq_wqe_size = rqshift;
++ qp->rq_wqe_size = info->rq_shift;
+ IRDMA_RING_INIT(qp->rq_ring, qp->rq_size);
+- qp->rq_wqe_size_multiplier = 1 << rqshift;
++ qp->rq_wqe_size_multiplier = 1 << info->rq_shift;
+ if (qp->uk_attrs->hw_rev == IRDMA_GEN_1)
+ qp->wqe_ops = iw_wqe_uk_ops_gen_1;
+ else
+diff --git a/drivers/infiniband/hw/irdma/user.h b/drivers/infiniband/hw/irdma/user.h
+index d0cdf609f5e06..1e0e1a71dbada 100644
+--- a/drivers/infiniband/hw/irdma/user.h
++++ b/drivers/infiniband/hw/irdma/user.h
+@@ -295,6 +295,12 @@ void irdma_uk_cq_init(struct irdma_cq_uk *cq,
+ struct irdma_cq_uk_init_info *info);
+ int irdma_uk_qp_init(struct irdma_qp_uk *qp,
+ struct irdma_qp_uk_init_info *info);
++void irdma_uk_calc_shift_wq(struct irdma_qp_uk_init_info *ukinfo, u8 *sq_shift,
++ u8 *rq_shift);
++int irdma_uk_calc_depth_shift_sq(struct irdma_qp_uk_init_info *ukinfo,
++ u32 *sq_depth, u8 *sq_shift);
++int irdma_uk_calc_depth_shift_rq(struct irdma_qp_uk_init_info *ukinfo,
++ u32 *rq_depth, u8 *rq_shift);
+ struct irdma_sq_uk_wr_trk_info {
+ u64 wrid;
+ u32 wr_len;
+@@ -374,8 +380,12 @@ struct irdma_qp_uk_init_info {
+ u32 max_sq_frag_cnt;
+ u32 max_rq_frag_cnt;
+ u32 max_inline_data;
++ u32 sq_depth;
++ u32 rq_depth;
+ u8 first_sq_wq;
+ u8 type;
++ u8 sq_shift;
++ u8 rq_shift;
+ int abi_ver;
+ bool legacy_mode;
+ };
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index 42c671f209233..bb423849968d9 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -277,7 +277,7 @@ static int irdma_alloc_ucontext(struct ib_ucontext *uctx,
+ struct irdma_alloc_ucontext_req req = {};
+ struct irdma_alloc_ucontext_resp uresp = {};
+ struct irdma_ucontext *ucontext = to_ucontext(uctx);
+- struct irdma_uk_attrs *uk_attrs;
++ struct irdma_uk_attrs *uk_attrs = &iwdev->rf->sc_dev.hw_attrs.uk_attrs;
+
+ if (udata->inlen < IRDMA_ALLOC_UCTX_MIN_REQ_LEN ||
+ udata->outlen < IRDMA_ALLOC_UCTX_MIN_RESP_LEN)
+@@ -292,7 +292,9 @@ static int irdma_alloc_ucontext(struct ib_ucontext *uctx,
+ ucontext->iwdev = iwdev;
+ ucontext->abi_ver = req.userspace_ver;
+
+- uk_attrs = &iwdev->rf->sc_dev.hw_attrs.uk_attrs;
++ if (req.comp_mask & IRDMA_ALLOC_UCTX_USE_RAW_ATTR)
++ ucontext->use_raw_attrs = true;
++
+ /* GEN_1 legacy support with libi40iw */
+ if (udata->outlen == IRDMA_ALLOC_UCTX_MIN_RESP_LEN) {
+ if (uk_attrs->hw_rev != IRDMA_GEN_1)
+@@ -327,6 +329,7 @@ static int irdma_alloc_ucontext(struct ib_ucontext *uctx,
+ uresp.max_hw_cq_size = uk_attrs->max_hw_cq_size;
+ uresp.min_hw_cq_size = uk_attrs->min_hw_cq_size;
+ uresp.hw_rev = uk_attrs->hw_rev;
++ uresp.comp_mask |= IRDMA_ALLOC_UCTX_USE_RAW_ATTR;
+ if (ib_copy_to_udata(udata, &uresp,
+ min(sizeof(uresp), udata->outlen))) {
+ rdma_user_mmap_entry_remove(ucontext->db_mmap_entry);
+@@ -566,6 +569,86 @@ static void irdma_setup_virt_qp(struct irdma_device *iwdev,
+ }
+ }
+
++/**
++ * irdma_setup_umode_qp - setup sq and rq size in user mode qp
++ * @iwdev: iwarp device
++ * @iwqp: qp ptr (user or kernel)
++ * @info: initialize info to return
++ * @init_attr: Initial QP create attributes
++ */
++static int irdma_setup_umode_qp(struct ib_udata *udata,
++ struct irdma_device *iwdev,
++ struct irdma_qp *iwqp,
++ struct irdma_qp_init_info *info,
++ struct ib_qp_init_attr *init_attr)
++{
++ struct irdma_ucontext *ucontext = rdma_udata_to_drv_context(udata,
++ struct irdma_ucontext, ibucontext);
++ struct irdma_qp_uk_init_info *ukinfo = &info->qp_uk_init_info;
++ struct irdma_create_qp_req req;
++ unsigned long flags;
++ int ret;
++
++ ret = ib_copy_from_udata(&req, udata,
++ min(sizeof(req), udata->inlen));
++ if (ret) {
++ ibdev_dbg(&iwdev->ibdev, "VERBS: ib_copy_from_data fail\n");
++ return ret;
++ }
++
++ iwqp->ctx_info.qp_compl_ctx = req.user_compl_ctx;
++ iwqp->user_mode = 1;
++ if (req.user_wqe_bufs) {
++ info->qp_uk_init_info.legacy_mode = ucontext->legacy_mode;
++ spin_lock_irqsave(&ucontext->qp_reg_mem_list_lock, flags);
++ iwqp->iwpbl = irdma_get_pbl((unsigned long)req.user_wqe_bufs,
++ &ucontext->qp_reg_mem_list);
++ spin_unlock_irqrestore(&ucontext->qp_reg_mem_list_lock, flags);
++
++ if (!iwqp->iwpbl) {
++ ret = -ENODATA;
++ ibdev_dbg(&iwdev->ibdev, "VERBS: no pbl info\n");
++ return ret;
++ }
++ }
++
++ if (!ucontext->use_raw_attrs) {
++ /**
++ * Maintain backward compat with older ABI which passes sq and
++ * rq depth in quanta in cap.max_send_wr and cap.max_recv_wr.
++ * There is no way to compute the correct value of
++ * iwqp->max_send_wr/max_recv_wr in the kernel.
++ */
++ iwqp->max_send_wr = init_attr->cap.max_send_wr;
++ iwqp->max_recv_wr = init_attr->cap.max_recv_wr;
++ ukinfo->sq_size = init_attr->cap.max_send_wr;
++ ukinfo->rq_size = init_attr->cap.max_recv_wr;
++ irdma_uk_calc_shift_wq(ukinfo, &ukinfo->sq_shift,
++ &ukinfo->rq_shift);
++ } else {
++ ret = irdma_uk_calc_depth_shift_sq(ukinfo, &ukinfo->sq_depth,
++ &ukinfo->sq_shift);
++ if (ret)
++ return ret;
++
++ ret = irdma_uk_calc_depth_shift_rq(ukinfo, &ukinfo->rq_depth,
++ &ukinfo->rq_shift);
++ if (ret)
++ return ret;
++
++ iwqp->max_send_wr =
++ (ukinfo->sq_depth - IRDMA_SQ_RSVD) >> ukinfo->sq_shift;
++ iwqp->max_recv_wr =
++ (ukinfo->rq_depth - IRDMA_RQ_RSVD) >> ukinfo->rq_shift;
++ ukinfo->sq_size = ukinfo->sq_depth >> ukinfo->sq_shift;
++ ukinfo->rq_size = ukinfo->rq_depth >> ukinfo->rq_shift;
++ }
++
++ irdma_setup_virt_qp(iwdev, iwqp, info);
++
++ return 0;
++}
++
+ /**
+ * irdma_setup_kmode_qp - setup initialization for kernel mode qp
+ * @iwdev: iwarp device
+@@ -579,40 +662,28 @@ static int irdma_setup_kmode_qp(struct irdma_device *iwdev,
+ struct ib_qp_init_attr *init_attr)
+ {
+ struct irdma_dma_mem *mem = &iwqp->kqp.dma_mem;
+- u32 sqdepth, rqdepth;
+- u8 sqshift, rqshift;
+ u32 size;
+ int status;
+ struct irdma_qp_uk_init_info *ukinfo = &info->qp_uk_init_info;
+- struct irdma_uk_attrs *uk_attrs = &iwdev->rf->sc_dev.hw_attrs.uk_attrs;
+
+- irdma_get_wqe_shift(uk_attrs,
+- uk_attrs->hw_rev >= IRDMA_GEN_2 ? ukinfo->max_sq_frag_cnt + 1 :
+- ukinfo->max_sq_frag_cnt,
+- ukinfo->max_inline_data, &sqshift);
+- status = irdma_get_sqdepth(uk_attrs, ukinfo->sq_size, sqshift,
+- &sqdepth);
++ status = irdma_uk_calc_depth_shift_sq(ukinfo, &ukinfo->sq_depth,
++ &ukinfo->sq_shift);
+ if (status)
+ return status;
+
+- if (uk_attrs->hw_rev == IRDMA_GEN_1)
+- rqshift = IRDMA_MAX_RQ_WQE_SHIFT_GEN1;
+- else
+- irdma_get_wqe_shift(uk_attrs, ukinfo->max_rq_frag_cnt, 0,
+- &rqshift);
+-
+- status = irdma_get_rqdepth(uk_attrs, ukinfo->rq_size, rqshift,
+- &rqdepth);
++ status = irdma_uk_calc_depth_shift_rq(ukinfo, &ukinfo->rq_depth,
++ &ukinfo->rq_shift);
+ if (status)
+ return status;
+
+ iwqp->kqp.sq_wrid_mem =
+- kcalloc(sqdepth, sizeof(*iwqp->kqp.sq_wrid_mem), GFP_KERNEL);
++ kcalloc(ukinfo->sq_depth, sizeof(*iwqp->kqp.sq_wrid_mem), GFP_KERNEL);
+ if (!iwqp->kqp.sq_wrid_mem)
+ return -ENOMEM;
+
+ iwqp->kqp.rq_wrid_mem =
+- kcalloc(rqdepth, sizeof(*iwqp->kqp.rq_wrid_mem), GFP_KERNEL);
++ kcalloc(ukinfo->rq_depth, sizeof(*iwqp->kqp.rq_wrid_mem), GFP_KERNEL);
++
+ if (!iwqp->kqp.rq_wrid_mem) {
+ kfree(iwqp->kqp.sq_wrid_mem);
+ iwqp->kqp.sq_wrid_mem = NULL;
+@@ -622,7 +693,7 @@ static int irdma_setup_kmode_qp(struct irdma_device *iwdev,
+ ukinfo->sq_wrtrk_array = iwqp->kqp.sq_wrid_mem;
+ ukinfo->rq_wrid_array = iwqp->kqp.rq_wrid_mem;
+
+- size = (sqdepth + rqdepth) * IRDMA_QP_WQE_MIN_SIZE;
++ size = (ukinfo->sq_depth + ukinfo->rq_depth) * IRDMA_QP_WQE_MIN_SIZE;
+ size += (IRDMA_SHADOW_AREA_SIZE << 3);
+
+ mem->size = ALIGN(size, 256);
+@@ -638,16 +709,19 @@ static int irdma_setup_kmode_qp(struct irdma_device *iwdev,
+
+ ukinfo->sq = mem->va;
+ info->sq_pa = mem->pa;
+- ukinfo->rq = &ukinfo->sq[sqdepth];
+- info->rq_pa = info->sq_pa + (sqdepth * IRDMA_QP_WQE_MIN_SIZE);
+- ukinfo->shadow_area = ukinfo->rq[rqdepth].elem;
+- info->shadow_area_pa = info->rq_pa + (rqdepth * IRDMA_QP_WQE_MIN_SIZE);
+- ukinfo->sq_size = sqdepth >> sqshift;
+- ukinfo->rq_size = rqdepth >> rqshift;
++ ukinfo->rq = &ukinfo->sq[ukinfo->sq_depth];
++ info->rq_pa = info->sq_pa + (ukinfo->sq_depth * IRDMA_QP_WQE_MIN_SIZE);
++ ukinfo->shadow_area = ukinfo->rq[ukinfo->rq_depth].elem;
++ info->shadow_area_pa =
++ info->rq_pa + (ukinfo->rq_depth * IRDMA_QP_WQE_MIN_SIZE);
++ ukinfo->sq_size = ukinfo->sq_depth >> ukinfo->sq_shift;
++ ukinfo->rq_size = ukinfo->rq_depth >> ukinfo->rq_shift;
+ ukinfo->qp_id = iwqp->ibqp.qp_num;
+
+- init_attr->cap.max_send_wr = (sqdepth - IRDMA_SQ_RSVD) >> sqshift;
+- init_attr->cap.max_recv_wr = (rqdepth - IRDMA_RQ_RSVD) >> rqshift;
++ iwqp->max_send_wr = (ukinfo->sq_depth - IRDMA_SQ_RSVD) >> ukinfo->sq_shift;
++ iwqp->max_recv_wr = (ukinfo->rq_depth - IRDMA_RQ_RSVD) >> ukinfo->rq_shift;
++ init_attr->cap.max_send_wr = iwqp->max_send_wr;
++ init_attr->cap.max_recv_wr = iwqp->max_recv_wr;
+
+ return 0;
+ }
+@@ -805,18 +879,14 @@ static int irdma_create_qp(struct ib_qp *ibqp,
+ struct irdma_device *iwdev = to_iwdev(ibpd->device);
+ struct irdma_pci_f *rf = iwdev->rf;
+ struct irdma_qp *iwqp = to_iwqp(ibqp);
+- struct irdma_create_qp_req req = {};
+ struct irdma_create_qp_resp uresp = {};
+ u32 qp_num = 0;
+ int err_code;
+- int sq_size;
+- int rq_size;
+ struct irdma_sc_qp *qp;
+ struct irdma_sc_dev *dev = &rf->sc_dev;
+ struct irdma_uk_attrs *uk_attrs = &dev->hw_attrs.uk_attrs;
+ struct irdma_qp_init_info init_info = {};
+ struct irdma_qp_host_ctx_info *ctx_info;
+- unsigned long flags;
+
+ err_code = irdma_validate_qp_attrs(init_attr, iwdev);
+ if (err_code)
+@@ -826,13 +896,10 @@ static int irdma_create_qp(struct ib_qp *ibqp,
+ udata->outlen < IRDMA_CREATE_QP_MIN_RESP_LEN))
+ return -EINVAL;
+
+- sq_size = init_attr->cap.max_send_wr;
+- rq_size = init_attr->cap.max_recv_wr;
+-
+ init_info.vsi = &iwdev->vsi;
+ init_info.qp_uk_init_info.uk_attrs = uk_attrs;
+- init_info.qp_uk_init_info.sq_size = sq_size;
+- init_info.qp_uk_init_info.rq_size = rq_size;
++ init_info.qp_uk_init_info.sq_size = init_attr->cap.max_send_wr;
++ init_info.qp_uk_init_info.rq_size = init_attr->cap.max_recv_wr;
+ init_info.qp_uk_init_info.max_sq_frag_cnt = init_attr->cap.max_send_sge;
+ init_info.qp_uk_init_info.max_rq_frag_cnt = init_attr->cap.max_recv_sge;
+ init_info.qp_uk_init_info.max_inline_data = init_attr->cap.max_inline_data;
+@@ -882,36 +949,9 @@ static int irdma_create_qp(struct ib_qp *ibqp,
+ init_waitqueue_head(&iwqp->mod_qp_waitq);
+
+ if (udata) {
+- err_code = ib_copy_from_udata(&req, udata,
+- min(sizeof(req), udata->inlen));
+- if (err_code) {
+- ibdev_dbg(&iwdev->ibdev,
+- "VERBS: ib_copy_from_data fail\n");
+- goto error;
+- }
+-
+- iwqp->ctx_info.qp_compl_ctx = req.user_compl_ctx;
+- iwqp->user_mode = 1;
+- if (req.user_wqe_bufs) {
+- struct irdma_ucontext *ucontext =
+- rdma_udata_to_drv_context(udata,
+- struct irdma_ucontext,
+- ibucontext);
+-
+- init_info.qp_uk_init_info.legacy_mode = ucontext->legacy_mode;
+- spin_lock_irqsave(&ucontext->qp_reg_mem_list_lock, flags);
+- iwqp->iwpbl = irdma_get_pbl((unsigned long)req.user_wqe_bufs,
+- &ucontext->qp_reg_mem_list);
+- spin_unlock_irqrestore(&ucontext->qp_reg_mem_list_lock, flags);
+-
+- if (!iwqp->iwpbl) {
+- err_code = -ENODATA;
+- ibdev_dbg(&iwdev->ibdev, "VERBS: no pbl info\n");
+- goto error;
+- }
+- }
+ init_info.qp_uk_init_info.abi_ver = iwpd->sc_pd.abi_ver;
+- irdma_setup_virt_qp(iwdev, iwqp, &init_info);
++ err_code = irdma_setup_umode_qp(udata, iwdev, iwqp, &init_info,
++ init_attr);
+ } else {
+ INIT_DELAYED_WORK(&iwqp->dwork_flush, irdma_flush_worker);
+ init_info.qp_uk_init_info.abi_ver = IRDMA_ABI_VER;
+@@ -966,8 +1006,6 @@ static int irdma_create_qp(struct ib_qp *ibqp,
+ spin_lock_init(&iwqp->sc_qp.pfpdu.lock);
+ iwqp->sig_all = (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) ? 1 : 0;
+ rf->qp_table[qp_num] = iwqp;
+- iwqp->max_send_wr = sq_size;
+- iwqp->max_recv_wr = rq_size;
+
+ if (rdma_protocol_roce(&iwdev->ibdev, 1)) {
+ if (dev->ws_add(&iwdev->vsi, 0)) {
+@@ -988,8 +1026,8 @@ static int irdma_create_qp(struct ib_qp *ibqp,
+ if (rdma_protocol_iwarp(&iwdev->ibdev, 1))
+ uresp.lsmm = 1;
+ }
+- uresp.actual_sq_size = sq_size;
+- uresp.actual_rq_size = rq_size;
++ uresp.actual_sq_size = init_info.qp_uk_init_info.sq_size;
++ uresp.actual_rq_size = init_info.qp_uk_init_info.rq_size;
+ uresp.qp_id = qp_num;
+ uresp.qp_caps = qp->qp_uk.qp_caps;
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.h b/drivers/infiniband/hw/irdma/verbs.h
+index 9f9e273bbff3e..0bc0d0faa0868 100644
+--- a/drivers/infiniband/hw/irdma/verbs.h
++++ b/drivers/infiniband/hw/irdma/verbs.h
+@@ -18,7 +18,8 @@ struct irdma_ucontext {
+ struct list_head qp_reg_mem_list;
+ spinlock_t qp_reg_mem_list_lock; /* protect QP memory list */
+ int abi_ver;
+- bool legacy_mode;
++ u8 legacy_mode : 1;
++ u8 use_raw_attrs : 1;
+ };
+
+ struct irdma_pd {
+diff --git a/include/uapi/rdma/irdma-abi.h b/include/uapi/rdma/irdma-abi.h
+index a7085e092d348..3a0cde4dcf331 100644
+--- a/include/uapi/rdma/irdma-abi.h
++++ b/include/uapi/rdma/irdma-abi.h
+@@ -22,10 +22,15 @@ enum irdma_memreg_type {
+ IRDMA_MEMREG_TYPE_CQ = 2,
+ };
+
++enum {
++ IRDMA_ALLOC_UCTX_USE_RAW_ATTR = 1 << 0,
++};
++
+ struct irdma_alloc_ucontext_req {
+ __u32 rsvd32;
+ __u8 userspace_ver;
+ __u8 rsvd8[3];
++ __aligned_u64 comp_mask;
+ };
+
+ struct irdma_alloc_ucontext_resp {
+@@ -46,6 +51,7 @@ struct irdma_alloc_ucontext_resp {
+ __u16 max_hw_sq_chunk;
+ __u8 hw_rev;
+ __u8 rsvd2;
++ __aligned_u64 comp_mask;
+ };
+
+ struct irdma_alloc_pd_resp {
+--
+2.43.0
+
--- /dev/null
+From d2f38023d84945d1cd631ef9e2c413891c22ade2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jan 2024 17:39:53 -0600
+Subject: RDMA/irdma: Remove duplicate assignment
+
+From: Mustafa Ismail <mustafa.ismail@intel.com>
+
+[ Upstream commit 926e8ea4b8dac84f6d14a4b60d0653f1f2ba9431 ]
+
+Remove the unneeded assignment of the qp_num which is already
+set in irdma_create_qp().
+
+Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
+Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
+Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
+Signed-off-by: Sindhu Devale <sindhu.devale@intel.com>
+Link: https://lore.kernel.org/r/20240131233953.400483-1-sindhu.devale@intel.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index bb423849968d9..76c5f461faca0 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -716,7 +716,6 @@ static int irdma_setup_kmode_qp(struct irdma_device *iwdev,
+ info->rq_pa + (ukinfo->rq_depth * IRDMA_QP_WQE_MIN_SIZE);
+ ukinfo->sq_size = ukinfo->sq_depth >> ukinfo->sq_shift;
+ ukinfo->rq_size = ukinfo->rq_depth >> ukinfo->rq_shift;
+- ukinfo->qp_id = iwqp->ibqp.qp_num;
+
+ iwqp->max_send_wr = (ukinfo->sq_depth - IRDMA_SQ_RSVD) >> ukinfo->sq_shift;
+ iwqp->max_recv_wr = (ukinfo->rq_depth - IRDMA_RQ_RSVD) >> ukinfo->rq_shift;
+@@ -941,7 +940,7 @@ static int irdma_create_qp(struct ib_qp *ibqp,
+ iwqp->host_ctx.size = IRDMA_QP_CTX_SIZE;
+
+ init_info.pd = &iwpd->sc_pd;
+- init_info.qp_uk_init_info.qp_id = iwqp->ibqp.qp_num;
++ init_info.qp_uk_init_info.qp_id = qp_num;
+ if (!rdma_protocol_roce(&iwdev->ibdev, 1))
+ init_info.qp_uk_init_info.first_sq_wq = 1;
+ iwqp->ctx_info.qp_compl_ctx = (uintptr_t)qp;
+--
+2.43.0
+
--- /dev/null
+From 3262106f6eac96ec1d24539a554f0f562cc86a35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Feb 2024 11:32:04 +0000
+Subject: RDMA/rtrs-clt: Check strnlen return len in sysfs mpath_policy_store()
+
+From: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+
+[ Upstream commit 7a7b7f575a25aa68ee934ee8107294487efcb3fe ]
+
+strnlen() may return 0 (e.g. for "\0\n" string), it's better to
+check the result of strnlen() before using 'len - 1' expression
+for the 'buf' array index.
+
+Detected using the static analysis tool - Svace.
+
+Fixes: dc3b66a0ce70 ("RDMA/rtrs-clt: Add a minimum latency multipath policy")
+Signed-off-by: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
+Link: https://lore.kernel.org/r/20240221113204.147478-1-aleksei.kodanev@bell-sw.com
+Acked-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c b/drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c
+index d3c436ead6946..4aa80c9388f05 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c
+@@ -133,7 +133,7 @@ static ssize_t mpath_policy_store(struct device *dev,
+
+ /* distinguish "mi" and "min-latency" with length */
+ len = strnlen(buf, NAME_MAX);
+- if (buf[len - 1] == '\n')
++ if (len && buf[len - 1] == '\n')
+ len--;
+
+ if (!strncasecmp(buf, "round-robin", 11) ||
+--
+2.43.0
+
--- /dev/null
+From 5613d201e024e415210d7c37011822cd38e12ea7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Feb 2024 02:15:49 -0700
+Subject: RDMA/srpt: Do not register event handler until srpt device is fully
+ setup
+
+From: William Kucharski <william.kucharski@oracle.com>
+
+[ Upstream commit c21a8870c98611e8f892511825c9607f1e2cd456 ]
+
+Upon rare occasions, KASAN reports a use-after-free Write
+in srpt_refresh_port().
+
+This seems to be because an event handler is registered before the
+srpt device is fully setup and a race condition upon error may leave a
+partially setup event handler in place.
+
+Instead, only register the event handler after srpt device initialization
+is complete.
+
+Fixes: a42d985bd5b2 ("ib_srpt: Initial SRP Target merge for v3.3-rc1")
+Signed-off-by: William Kucharski <william.kucharski@oracle.com>
+Link: https://lore.kernel.org/r/20240202091549.991784-2-william.kucharski@oracle.com
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/srpt/ib_srpt.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
+index cffa93f114a73..fd6c260d5857d 100644
+--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
++++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
+@@ -3209,7 +3209,6 @@ static int srpt_add_one(struct ib_device *device)
+
+ INIT_IB_EVENT_HANDLER(&sdev->event_handler, sdev->device,
+ srpt_event_handler);
+- ib_register_event_handler(&sdev->event_handler);
+
+ for (i = 1; i <= sdev->device->phys_port_cnt; i++) {
+ sport = &sdev->port[i - 1];
+@@ -3232,6 +3231,7 @@ static int srpt_add_one(struct ib_device *device)
+ }
+ }
+
++ ib_register_event_handler(&sdev->event_handler);
+ spin_lock(&srpt_dev_lock);
+ list_add_tail(&sdev->list, &srpt_dev_list);
+ spin_unlock(&srpt_dev_lock);
+@@ -3242,7 +3242,6 @@ static int srpt_add_one(struct ib_device *device)
+
+ err_port:
+ srpt_unregister_mad_agent(sdev, i);
+- ib_unregister_event_handler(&sdev->event_handler);
+ err_cm:
+ if (sdev->cm_id)
+ ib_destroy_cm_id(sdev->cm_id);
+--
+2.43.0
+
--- /dev/null
+From 532872c0799a2143576e5523370a6a38476f760b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Feb 2024 17:27:18 +0800
+Subject: rtc: test: Fix invalid format specifier.
+
+From: David Gow <davidgow@google.com>
+
+[ Upstream commit 8a904a3caa88118744062e872ae90f37748a8fd8 ]
+
+'days' is a s64 (from div_s64), and so should use a %lld specifier.
+
+This was found by extending KUnit's assertion macros to use gcc's
+__printf attribute.
+
+Fixes: 1d1bb12a8b18 ("rtc: Improve performance of rtc_time64_to_tm(). Add tests.")
+Signed-off-by: David Gow <davidgow@google.com>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Justin Stitt <justinstitt@google.com>
+Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/rtc/lib_test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/rtc/lib_test.c b/drivers/rtc/lib_test.c
+index d5caf36c56cdc..225c859d6da55 100644
+--- a/drivers/rtc/lib_test.c
++++ b/drivers/rtc/lib_test.c
+@@ -54,7 +54,7 @@ static void rtc_time64_to_tm_test_date_range(struct kunit *test)
+
+ days = div_s64(secs, 86400);
+
+- #define FAIL_MSG "%d/%02d/%02d (%2d) : %ld", \
++ #define FAIL_MSG "%d/%02d/%02d (%2d) : %lld", \
+ year, month, mday, yday, days
+
+ KUNIT_ASSERT_EQ_MSG(test, year - 1900, result.tm_year, FAIL_MSG);
+--
+2.43.0
+
--- /dev/null
+From ac8ab3dc4c96515b15ae35c36d097d053353449d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Mar 2024 20:22:09 +0100
+Subject: s390/cache: prevent rebuild of shared_cpu_list
+
+From: Heiko Carstens <hca@linux.ibm.com>
+
+[ Upstream commit cb0cd4ee11142339f2d47eef6db274290b7a482d ]
+
+With commit 36bbc5b4ffab ("cacheinfo: Allow early detection and population
+of cache attributes") the shared cpu list for each cache level higher than
+L1 is rebuilt even if the list already has been set up.
+
+This is caused by the removal of the cpumask_empty() check within
+cache_shared_cpu_map_setup().
+
+However architectures can enforce that the shared cpu list is not rebuilt
+by simply setting cpu_map_populated of the per cpu cache info structure to
+true, which is also the fix for this problem.
+
+Before:
+$ cat /sys/devices/system/cpu/cpu1/cache/index2/shared_cpu_list
+0-7
+
+After:
+$ cat /sys/devices/system/cpu/cpu1/cache/index2/shared_cpu_list
+1
+
+Fixes: 36bbc5b4ffab ("cacheinfo: Allow early detection and population of cache attributes")
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/cache.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/s390/kernel/cache.c b/arch/s390/kernel/cache.c
+index 7ee3651d00abe..732024ca005ad 100644
+--- a/arch/s390/kernel/cache.c
++++ b/arch/s390/kernel/cache.c
+@@ -166,5 +166,6 @@ int populate_cache_leaves(unsigned int cpu)
+ ci_leaf_init(this_leaf++, pvt, ctype, level, cpu);
+ }
+ }
++ this_cpu_ci->cpu_map_populated = true;
+ return 0;
+ }
+--
+2.43.0
+
--- /dev/null
+From f04772c6b14ab805fe3d4ef40bb2e2649c8aad78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Apr 2023 16:20:12 +0200
+Subject: s390/dasd: add autoquiesce feature
+
+From: Stefan Haberland <sth@linux.ibm.com>
+
+[ Upstream commit 1cee2975bbabd89df1097c354867192106b058ea ]
+
+Add the internal logic to check for autoquiesce triggers and handle
+them.
+
+Quiesce and resume are functions that tell Linux to stop/resume
+issuing I/Os to a specific DASD.
+The DASD driver allows a manual quiesce/resume via ioctl.
+
+Autoquiesce will define an amount of triggers that will lead to
+an automatic quiesce if a certain event occurs.
+There is no automatic resume.
+
+All events will be reported via DASD Extended Error Reporting (EER)
+if configured.
+
+Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
+Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
+Reviewed-by: Halil Pasic <pasic@linux.ibm.com>
+Link: https://lore.kernel.org/r/20230405142017.2446986-3-sth@linux.ibm.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: c3116e62ddef ("s390/dasd: fix double module refcount decrement")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/include/uapi/asm/dasd.h | 2 ++
+ drivers/s390/block/dasd.c | 60 ++++++++++++++++++++++---------
+ drivers/s390/block/dasd_eer.c | 1 +
+ drivers/s390/block/dasd_int.h | 2 ++
+ 4 files changed, 48 insertions(+), 17 deletions(-)
+
+diff --git a/arch/s390/include/uapi/asm/dasd.h b/arch/s390/include/uapi/asm/dasd.h
+index 93d1ccd3304c7..9c49c3d67cd56 100644
+--- a/arch/s390/include/uapi/asm/dasd.h
++++ b/arch/s390/include/uapi/asm/dasd.h
+@@ -78,6 +78,7 @@ typedef struct dasd_information2_t {
+ * 0x040: give access to raw eckd data
+ * 0x080: enable discard support
+ * 0x100: enable autodisable for IFCC errors (default)
++ * 0x200: enable requeue of all requests on autoquiesce
+ */
+ #define DASD_FEATURE_READONLY 0x001
+ #define DASD_FEATURE_USEDIAG 0x002
+@@ -88,6 +89,7 @@ typedef struct dasd_information2_t {
+ #define DASD_FEATURE_USERAW 0x040
+ #define DASD_FEATURE_DISCARD 0x080
+ #define DASD_FEATURE_PATH_AUTODISABLE 0x100
++#define DASD_FEATURE_REQUEUEQUIESCE 0x200
+ #define DASD_FEATURE_DEFAULT DASD_FEATURE_PATH_AUTODISABLE
+
+ #define DASD_PARTN_BITS 2
+diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
+index f207de4a87a0f..2f6976671496f 100644
+--- a/drivers/s390/block/dasd.c
++++ b/drivers/s390/block/dasd.c
+@@ -73,7 +73,8 @@ static void dasd_profile_init(struct dasd_profile *, struct dentry *);
+ static void dasd_profile_exit(struct dasd_profile *);
+ static void dasd_hosts_init(struct dentry *, struct dasd_device *);
+ static void dasd_hosts_exit(struct dasd_device *);
+-
++static int dasd_handle_autoquiesce(struct dasd_device *, struct dasd_ccw_req *,
++ unsigned int);
+ /*
+ * SECTION: Operations on the device structure.
+ */
+@@ -2327,7 +2328,7 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible)
+ /* Non-temporary stop condition will trigger fail fast */
+ if (device->stopped & ~DASD_STOPPED_PENDING &&
+ test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
+- (!dasd_eer_enabled(device))) {
++ !dasd_eer_enabled(device) && device->aq_mask == 0) {
+ cqr->status = DASD_CQR_FAILED;
+ cqr->intrc = -ENOLINK;
+ continue;
+@@ -2803,20 +2804,18 @@ static void __dasd_process_block_ccw_queue(struct dasd_block *block,
+ dasd_log_sense(cqr, &cqr->irb);
+ }
+
+- /* First of all call extended error reporting. */
+- if (dasd_eer_enabled(base) &&
+- cqr->status == DASD_CQR_FAILED) {
+- dasd_eer_write(base, cqr, DASD_EER_FATALERROR);
+-
+- /* restart request */
++ /*
++ * First call extended error reporting and check for autoquiesce
++ */
++ spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
++ if (cqr->status == DASD_CQR_FAILED &&
++ dasd_handle_autoquiesce(base, cqr, DASD_EER_FATALERROR)) {
+ cqr->status = DASD_CQR_FILLED;
+ cqr->retries = 255;
+- spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
+- dasd_device_set_stop_bits(base, DASD_STOPPED_QUIESCE);
+- spin_unlock_irqrestore(get_ccwdev_lock(base->cdev),
+- flags);
++ spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
+ goto restart;
+ }
++ spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
+
+ /* Process finished ERP request. */
+ if (cqr->refers) {
+@@ -2858,7 +2857,7 @@ static void __dasd_block_start_head(struct dasd_block *block)
+ /* Non-temporary stop condition will trigger fail fast */
+ if (block->base->stopped & ~DASD_STOPPED_PENDING &&
+ test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
+- (!dasd_eer_enabled(block->base))) {
++ !dasd_eer_enabled(block->base) && block->base->aq_mask == 0) {
+ cqr->status = DASD_CQR_FAILED;
+ cqr->intrc = -ENOLINK;
+ dasd_schedule_block_bh(block);
+@@ -3682,8 +3681,8 @@ int dasd_generic_last_path_gone(struct dasd_device *device)
+ dev_warn(&device->cdev->dev, "No operational channel path is left "
+ "for the device\n");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s", "last path gone");
+- /* First of all call extended error reporting. */
+- dasd_eer_write(device, NULL, DASD_EER_NOPATH);
++ /* First call extended error reporting and check for autoquiesce. */
++ dasd_handle_autoquiesce(device, NULL, DASD_EER_NOPATH);
+
+ if (device->state < DASD_STATE_BASIC)
+ return 0;
+@@ -3815,7 +3814,8 @@ void dasd_generic_path_event(struct ccw_device *cdev, int *path_event)
+ "No verified channel paths remain for the device\n");
+ DBF_DEV_EVENT(DBF_WARNING, device,
+ "%s", "last verified path gone");
+- dasd_eer_write(device, NULL, DASD_EER_NOPATH);
++ /* First call extended error reporting and check for autoquiesce. */
++ dasd_handle_autoquiesce(device, NULL, DASD_EER_NOPATH);
+ dasd_device_set_stop_bits(device,
+ DASD_STOPPED_DC_WAIT);
+ }
+@@ -3837,7 +3837,8 @@ EXPORT_SYMBOL_GPL(dasd_generic_verify_path);
+ void dasd_generic_space_exhaust(struct dasd_device *device,
+ struct dasd_ccw_req *cqr)
+ {
+- dasd_eer_write(device, NULL, DASD_EER_NOSPC);
++ /* First call extended error reporting and check for autoquiesce. */
++ dasd_handle_autoquiesce(device, NULL, DASD_EER_NOSPC);
+
+ if (device->state < DASD_STATE_BASIC)
+ return;
+@@ -3931,6 +3932,31 @@ void dasd_schedule_requeue(struct dasd_device *device)
+ }
+ EXPORT_SYMBOL(dasd_schedule_requeue);
+
++static int dasd_handle_autoquiesce(struct dasd_device *device,
++ struct dasd_ccw_req *cqr,
++ unsigned int reason)
++{
++ /* in any case write eer message with reason */
++ if (dasd_eer_enabled(device))
++ dasd_eer_write(device, cqr, reason);
++
++ if (!test_bit(reason, &device->aq_mask))
++ return 0;
++
++ /* notify eer about autoquiesce */
++ if (dasd_eer_enabled(device))
++ dasd_eer_write(device, NULL, DASD_EER_AUTOQUIESCE);
++
++ pr_info("%s: The DASD has been put in the quiesce state\n",
++ dev_name(&device->cdev->dev));
++ dasd_device_set_stop_bits(device, DASD_STOPPED_QUIESCE);
++
++ if (device->features & DASD_FEATURE_REQUEUEQUIESCE)
++ dasd_schedule_requeue(device);
++
++ return 1;
++}
++
+ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
+ int rdc_buffer_size,
+ int magic)
+diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
+index d4d31cd11d261..d16c699b9ac6d 100644
+--- a/drivers/s390/block/dasd_eer.c
++++ b/drivers/s390/block/dasd_eer.c
+@@ -387,6 +387,7 @@ void dasd_eer_write(struct dasd_device *device, struct dasd_ccw_req *cqr,
+ break;
+ case DASD_EER_NOPATH:
+ case DASD_EER_NOSPC:
++ case DASD_EER_AUTOQUIESCE:
+ dasd_eer_write_standard_trigger(device, NULL, id);
+ break;
+ case DASD_EER_STATECHANGE:
+diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
+index f50932518f83a..00bcd177264ac 100644
+--- a/drivers/s390/block/dasd_int.h
++++ b/drivers/s390/block/dasd_int.h
+@@ -464,6 +464,7 @@ extern struct dasd_discipline *dasd_diag_discipline_pointer;
+ #define DASD_EER_STATECHANGE 3
+ #define DASD_EER_PPRCSUSPEND 4
+ #define DASD_EER_NOSPC 5
++#define DASD_EER_AUTOQUIESCE 31
+
+ /* DASD path handling */
+
+@@ -641,6 +642,7 @@ struct dasd_device {
+ struct dasd_format_entry format_entry;
+ struct kset *paths_info;
+ struct dasd_copy_relation *copy;
++ unsigned long aq_mask;
+ };
+
+ struct dasd_block {
+--
+2.43.0
+
--- /dev/null
+From fccbf781ce4b2da3d7a6424764c5ae6cc55b5b70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Feb 2024 13:45:22 +0100
+Subject: s390/dasd: fix double module refcount decrement
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Miroslav Franc <mfranc@suse.cz>
+
+[ Upstream commit c3116e62ddeff79cae342147753ce596f01fcf06 ]
+
+Once the discipline is associated with the device, deleting the device
+takes care of decrementing the module's refcount. Doing it manually on
+this error path causes refcount to artificially decrease on each error
+while it should just stay the same.
+
+Fixes: c020d722b110 ("s390/dasd: fix panic during offline processing")
+Signed-off-by: Miroslav Franc <mfranc@suse.cz>
+Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
+Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
+Link: https://lore.kernel.org/r/20240209124522.3697827-3-sth@linux.ibm.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/block/dasd.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
+index 029bb9e15ad90..341d65acd715d 100644
+--- a/drivers/s390/block/dasd.c
++++ b/drivers/s390/block/dasd.c
+@@ -3512,12 +3512,11 @@ int dasd_generic_set_online(struct ccw_device *cdev,
+ dasd_delete_device(device);
+ return -EINVAL;
+ }
++ device->base_discipline = base_discipline;
+ if (!try_module_get(discipline->owner)) {
+- module_put(base_discipline->owner);
+ dasd_delete_device(device);
+ return -EINVAL;
+ }
+- device->base_discipline = base_discipline;
+ device->discipline = discipline;
+
+ /* check_device will allocate block device if necessary */
+@@ -3525,8 +3524,6 @@ int dasd_generic_set_online(struct ccw_device *cdev,
+ if (rc) {
+ dev_warn(dev, "Setting the DASD online with discipline %s failed with rc=%i\n",
+ discipline->name, rc);
+- module_put(discipline->owner);
+- module_put(base_discipline->owner);
+ dasd_delete_device(device);
+ return rc;
+ }
+--
+2.43.0
+
--- /dev/null
+From b0756126c132be98da8894455051bcb60bad1c8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Feb 2024 17:42:48 +0100
+Subject: s390/dasd: Use dev_*() for device log messages
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jan Höppner <hoeppner@linux.ibm.com>
+
+[ Upstream commit 79ae56fc475869d636071f66d9e4ef2a3819eee6 ]
+
+All log messages in dasd.c use the printk variants of pr_*(). They all
+add the name of the affected device manually to the log message.
+This can be simplified by using the dev_*() variants of printk, which
+include the device information and make a separate call to dev_name()
+unnecessary.
+
+The KMSG_COMPONENT and the pr_fmt() definition can be dropped. Note that
+this removes the "dasd: " prefix from the one pr_info() call in
+dasd_init(). However, the log message already provides all relevant
+information.
+
+Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
+Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
+Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
+Link: https://lore.kernel.org/r/20240208164248.540985-10-sth@linux.ibm.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: c3116e62ddef ("s390/dasd: fix double module refcount decrement")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/block/dasd.c | 50 +++++++++++++++++++--------------------
+ 1 file changed, 24 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
+index 2f6976671496f..029bb9e15ad90 100644
+--- a/drivers/s390/block/dasd.c
++++ b/drivers/s390/block/dasd.c
+@@ -8,9 +8,6 @@
+ * Copyright IBM Corp. 1999, 2009
+ */
+
+-#define KMSG_COMPONENT "dasd"
+-#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+-
+ #include <linux/kmod.h>
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+@@ -3390,8 +3387,7 @@ static void dasd_generic_auto_online(void *data, async_cookie_t cookie)
+
+ ret = ccw_device_set_online(cdev);
+ if (ret)
+- pr_warn("%s: Setting the DASD online failed with rc=%d\n",
+- dev_name(&cdev->dev), ret);
++ dev_warn(&cdev->dev, "Setting the DASD online failed with rc=%d\n", ret);
+ }
+
+ /*
+@@ -3478,8 +3474,11 @@ int dasd_generic_set_online(struct ccw_device *cdev,
+ {
+ struct dasd_discipline *discipline;
+ struct dasd_device *device;
++ struct device *dev;
+ int rc;
+
++ dev = &cdev->dev;
++
+ /* first online clears initial online feature flag */
+ dasd_set_feature(cdev, DASD_FEATURE_INITIAL_ONLINE, 0);
+ device = dasd_create_device(cdev);
+@@ -3492,11 +3491,10 @@ int dasd_generic_set_online(struct ccw_device *cdev,
+ /* Try to load the required module. */
+ rc = request_module(DASD_DIAG_MOD);
+ if (rc) {
+- pr_warn("%s Setting the DASD online failed "
+- "because the required module %s "
+- "could not be loaded (rc=%d)\n",
+- dev_name(&cdev->dev), DASD_DIAG_MOD,
+- rc);
++ dev_warn(dev, "Setting the DASD online failed "
++ "because the required module %s "
++ "could not be loaded (rc=%d)\n",
++ DASD_DIAG_MOD, rc);
+ dasd_delete_device(device);
+ return -ENODEV;
+ }
+@@ -3504,8 +3502,7 @@ int dasd_generic_set_online(struct ccw_device *cdev,
+ /* Module init could have failed, so check again here after
+ * request_module(). */
+ if (!dasd_diag_discipline_pointer) {
+- pr_warn("%s Setting the DASD online failed because of missing DIAG discipline\n",
+- dev_name(&cdev->dev));
++ dev_warn(dev, "Setting the DASD online failed because of missing DIAG discipline\n");
+ dasd_delete_device(device);
+ return -ENODEV;
+ }
+@@ -3526,8 +3523,8 @@ int dasd_generic_set_online(struct ccw_device *cdev,
+ /* check_device will allocate block device if necessary */
+ rc = discipline->check_device(device);
+ if (rc) {
+- pr_warn("%s Setting the DASD online with discipline %s failed with rc=%i\n",
+- dev_name(&cdev->dev), discipline->name, rc);
++ dev_warn(dev, "Setting the DASD online with discipline %s failed with rc=%i\n",
++ discipline->name, rc);
+ module_put(discipline->owner);
+ module_put(base_discipline->owner);
+ dasd_delete_device(device);
+@@ -3536,16 +3533,15 @@ int dasd_generic_set_online(struct ccw_device *cdev,
+
+ dasd_set_target_state(device, DASD_STATE_ONLINE);
+ if (device->state <= DASD_STATE_KNOWN) {
+- pr_warn("%s Setting the DASD online failed because of a missing discipline\n",
+- dev_name(&cdev->dev));
++ dev_warn(dev, "Setting the DASD online failed because of a missing discipline\n");
+ rc = -ENODEV;
+ dasd_set_target_state(device, DASD_STATE_NEW);
+ if (device->block)
+ dasd_free_block(device->block);
+ dasd_delete_device(device);
+- } else
+- pr_debug("dasd_generic device %s found\n",
+- dev_name(&cdev->dev));
++ } else {
++ dev_dbg(dev, "dasd_generic device found\n");
++ }
+
+ wait_event(dasd_init_waitq, _wait_for_device(device));
+
+@@ -3556,10 +3552,13 @@ EXPORT_SYMBOL_GPL(dasd_generic_set_online);
+
+ int dasd_generic_set_offline(struct ccw_device *cdev)
+ {
++ int max_count, open_count, rc;
+ struct dasd_device *device;
+ struct dasd_block *block;
+- int max_count, open_count, rc;
+ unsigned long flags;
++ struct device *dev;
++
++ dev = &cdev->dev;
+
+ rc = 0;
+ spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
+@@ -3580,11 +3579,10 @@ int dasd_generic_set_offline(struct ccw_device *cdev)
+ open_count = atomic_read(&device->block->open_count);
+ if (open_count > max_count) {
+ if (open_count > 0)
+- pr_warn("%s: The DASD cannot be set offline with open count %i\n",
+- dev_name(&cdev->dev), open_count);
++ dev_warn(dev, "The DASD cannot be set offline with open count %i\n",
++ open_count);
+ else
+- pr_warn("%s: The DASD cannot be set offline while it is in use\n",
+- dev_name(&cdev->dev));
++ dev_warn(dev, "The DASD cannot be set offline while it is in use\n");
+ rc = -EBUSY;
+ goto out_err;
+ }
+@@ -3947,8 +3945,8 @@ static int dasd_handle_autoquiesce(struct dasd_device *device,
+ if (dasd_eer_enabled(device))
+ dasd_eer_write(device, NULL, DASD_EER_AUTOQUIESCE);
+
+- pr_info("%s: The DASD has been put in the quiesce state\n",
+- dev_name(&device->cdev->dev));
++ dev_info(&device->cdev->dev,
++ "The DASD has been put in the quiesce state\n");
+ dasd_device_set_stop_bits(device, DASD_STOPPED_QUIESCE);
+
+ if (device->features & DASD_FEATURE_REQUEUEQUIESCE)
+--
+2.43.0
+
--- /dev/null
+From c9ec3623f088a062894d6fe9de5980732d9886fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Jan 2024 13:03:39 +0100
+Subject: s390/pai: fix attr_event_free upper limit for pai device drivers
+
+From: Thomas Richter <tmricht@linux.ibm.com>
+
+[ Upstream commit 225d09d6e5f3870560665a1829d2db79330b4c58 ]
+
+When the device drivers are initialized, a sysfs directory
+is created. This contains many attributes which are allocated with
+kzalloc(). Should it fail, the memory for the attributes already
+created is freed in attr_event_free(). Its second parameter is number
+of attribute elements to delete. This parameter is off by one.
+When i. e. the 10th attribute fails to get created, attributes
+numbered 0 to 9 should be deleted. Currently only attributes
+numbered 0 to 8 are deleted.
+
+Fixes: 39d62336f5c1 ("s390/pai: add support for cryptography counters")
+Reported-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
+Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/perf_pai_crypto.c | 2 +-
+ arch/s390/kernel/perf_pai_ext.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c
+index 6826e2a69a216..f61a652046cfb 100644
+--- a/arch/s390/kernel/perf_pai_crypto.c
++++ b/arch/s390/kernel/perf_pai_crypto.c
+@@ -647,7 +647,7 @@ static int __init attr_event_init(void)
+ for (i = 0; i < ARRAY_SIZE(paicrypt_ctrnames); i++) {
+ ret = attr_event_init_one(attrs, i);
+ if (ret) {
+- attr_event_free(attrs, i - 1);
++ attr_event_free(attrs, i);
+ return ret;
+ }
+ }
+diff --git a/arch/s390/kernel/perf_pai_ext.c b/arch/s390/kernel/perf_pai_ext.c
+index 74b53c531e0cd..b4d89654183a2 100644
+--- a/arch/s390/kernel/perf_pai_ext.c
++++ b/arch/s390/kernel/perf_pai_ext.c
+@@ -612,7 +612,7 @@ static int __init attr_event_init(void)
+ for (i = 0; i < ARRAY_SIZE(paiext_ctrnames); i++) {
+ ret = attr_event_init_one(attrs, i);
+ if (ret) {
+- attr_event_free(attrs, i - 1);
++ attr_event_free(attrs, i);
+ return ret;
+ }
+ }
+--
+2.43.0
+
--- /dev/null
+From c89cf98d1655b2639b433b714f21996f3542a106 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Jan 2024 20:14:28 -0700
+Subject: s390/vdso: drop '-fPIC' from LDFLAGS
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit 0628c03934187be33942580e10bb9afcc61adeed ]
+
+'-fPIC' as an option to the linker does not do what it seems like it
+should. With ld.bfd, it is treated as '-f PIC', which does not make
+sense based on the meaning of '-f':
+
+ -f SHLIB, --auxiliary SHLIB Auxiliary filter for shared object symbol table
+
+When building with ld.lld (currently under review in a GitHub pull
+request), it just errors out because '-f' means nothing and neither does
+'-fPIC':
+
+ ld.lld: error: unknown argument '-fPIC'
+
+'-fPIC' was blindly copied from CFLAGS when the vDSO stopped being
+linked with '$(CC)', it should not be needed. Remove it to clear up the
+build failure with ld.lld.
+
+Fixes: 2b2a25845d53 ("s390/vdso: Use $(LD) instead of $(CC) to link vDSO")
+Link: https://github.com/llvm/llvm-project/pull/75643
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Reviewed-by: Fangrui Song <maskray@google.com>
+Link: https://lore.kernel.org/r/20240130-s390-vdso-drop-fpic-from-ldflags-v1-1-094ad104fc55@kernel.org
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/vdso32/Makefile | 2 +-
+ arch/s390/kernel/vdso64/Makefile | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/s390/kernel/vdso32/Makefile b/arch/s390/kernel/vdso32/Makefile
+index 245bddfe9bc0e..cc513add48eb5 100644
+--- a/arch/s390/kernel/vdso32/Makefile
++++ b/arch/s390/kernel/vdso32/Makefile
+@@ -22,7 +22,7 @@ KBUILD_AFLAGS_32 += -m31 -s
+ KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS))
+ KBUILD_CFLAGS_32 += -m31 -fPIC -shared -fno-common -fno-builtin
+
+-LDFLAGS_vdso32.so.dbg += -fPIC -shared -soname=linux-vdso32.so.1 \
++LDFLAGS_vdso32.so.dbg += -shared -soname=linux-vdso32.so.1 \
+ --hash-style=both --build-id=sha1 -melf_s390 -T
+
+ $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_32)
+diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile
+index 1605ba45ac4c0..42d918d50a1ff 100644
+--- a/arch/s390/kernel/vdso64/Makefile
++++ b/arch/s390/kernel/vdso64/Makefile
+@@ -26,7 +26,7 @@ KBUILD_AFLAGS_64 += -m64 -s
+
+ KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS))
+ KBUILD_CFLAGS_64 += -m64 -fPIC -fno-common -fno-builtin
+-ldflags-y := -fPIC -shared -soname=linux-vdso64.so.1 \
++ldflags-y := -shared -soname=linux-vdso64.so.1 \
+ --hash-style=both --build-id=sha1 -T
+
+ $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_64)
+--
+2.43.0
+
--- /dev/null
+From 768f14c81ca6c8eaa18beca0c84defa3df997b8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jan 2024 14:17:06 +0100
+Subject: sched/fair: Take the scheduling domain into account in
+ select_idle_smt()
+
+From: Keisuke Nishimura <keisuke.nishimura@inria.fr>
+
+[ Upstream commit 8aeaffef8c6eceab0e1498486fdd4f3dc3b7066c ]
+
+When picking a CPU on task wakeup, select_idle_smt() has to take
+into account the scheduling domain of @target. This is because the
+"isolcpus" kernel command line option can remove CPUs from the domain to
+isolate them from other SMT siblings.
+
+This fix checks if the candidate CPU is in the target scheduling domain.
+
+Commit:
+
+ df3cb4ea1fb6 ("sched/fair: Fix wrong cpu selecting from isolated domain")
+
+... originally introduced this fix by adding the check of the scheduling
+domain in the loop.
+
+However, commit:
+
+ 3e6efe87cd5cc ("sched/fair: Remove redundant check in select_idle_smt()")
+
+... accidentally removed the check. Bring it back.
+
+Fixes: 3e6efe87cd5c ("sched/fair: Remove redundant check in select_idle_smt()")
+Signed-off-by: Keisuke Nishimura <keisuke.nishimura@inria.fr>
+Signed-off-by: Julia Lawall <julia.lawall@inria.fr>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>
+Link: https://lore.kernel.org/r/20240110131707.437301-1-keisuke.nishimura@inria.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index 2558ab9033bee..1c4e54fffb8b6 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -6678,13 +6678,19 @@ static int select_idle_core(struct task_struct *p, int core, struct cpumask *cpu
+ /*
+ * Scan the local SMT mask for idle CPUs.
+ */
+-static int select_idle_smt(struct task_struct *p, int target)
++static int select_idle_smt(struct task_struct *p, struct sched_domain *sd, int target)
+ {
+ int cpu;
+
+ for_each_cpu_and(cpu, cpu_smt_mask(target), p->cpus_ptr) {
+ if (cpu == target)
+ continue;
++ /*
++ * Check if the CPU is in the LLC scheduling domain of @target.
++ * Due to isolcpus, there is no guarantee that all the siblings are in the domain.
++ */
++ if (!cpumask_test_cpu(cpu, sched_domain_span(sd)))
++ continue;
+ if (available_idle_cpu(cpu) || sched_idle_cpu(cpu))
+ return cpu;
+ }
+@@ -6708,7 +6714,7 @@ static inline int select_idle_core(struct task_struct *p, int core, struct cpuma
+ return __select_idle_cpu(core, p);
+ }
+
+-static inline int select_idle_smt(struct task_struct *p, int target)
++static inline int select_idle_smt(struct task_struct *p, struct sched_domain *sd, int target)
+ {
+ return -1;
+ }
+@@ -6970,7 +6976,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
+ has_idle_core = test_idle_cores(target);
+
+ if (!has_idle_core && cpus_share_cache(prev, target)) {
+- i = select_idle_smt(p, prev);
++ i = select_idle_smt(p, sd, prev);
+ if ((unsigned int)i < nr_cpumask_bits)
+ return i;
+ }
+--
+2.43.0
+
--- /dev/null
+From cd95ee4a01095d18f5989af39f5351ec95a9ebdb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jan 2024 14:17:07 +0100
+Subject: sched/fair: Take the scheduling domain into account in
+ select_idle_core()
+
+From: Keisuke Nishimura <keisuke.nishimura@inria.fr>
+
+[ Upstream commit 23d04d8c6b8ec339057264659b7834027f3e6a63 ]
+
+When picking a CPU on task wakeup, select_idle_core() has to take
+into account the scheduling domain where the function looks for the CPU.
+
+This is because the "isolcpus" kernel command line option can remove CPUs
+from the domain to isolate them from other SMT siblings.
+
+This change replaces the set of CPUs allowed to run the task from
+p->cpus_ptr by the intersection of p->cpus_ptr and sched_domain_span(sd)
+which is stored in the 'cpus' argument provided by select_idle_cpu().
+
+Fixes: 9fe1f127b913 ("sched/fair: Merge select_idle_core/cpu()")
+Signed-off-by: Keisuke Nishimura <keisuke.nishimura@inria.fr>
+Signed-off-by: Julia Lawall <julia.lawall@inria.fr>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/r/20240110131707.437301-2-keisuke.nishimura@inria.fr
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/sched/fair.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index 1c4e54fffb8b6..91c101ecfef9f 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -6656,7 +6656,7 @@ static int select_idle_core(struct task_struct *p, int core, struct cpumask *cpu
+ if (!available_idle_cpu(cpu)) {
+ idle = false;
+ if (*idle_cpu == -1) {
+- if (sched_idle_cpu(cpu) && cpumask_test_cpu(cpu, p->cpus_ptr)) {
++ if (sched_idle_cpu(cpu) && cpumask_test_cpu(cpu, cpus)) {
+ *idle_cpu = cpu;
+ break;
+ }
+@@ -6664,7 +6664,7 @@ static int select_idle_core(struct task_struct *p, int core, struct cpumask *cpu
+ }
+ break;
+ }
+- if (*idle_cpu == -1 && cpumask_test_cpu(cpu, p->cpus_ptr))
++ if (*idle_cpu == -1 && cpumask_test_cpu(cpu, cpus))
+ *idle_cpu = cpu;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 060a5f3dd6b9e2ae123a6338f1c2beb52ff51bd0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Feb 2024 13:44:06 +0100
+Subject: scsi: bfa: Fix function pointer type mismatch for hcb_qe->cbfn
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit b69600231f751304db914c63b937f7098ed2895c ]
+
+Some callback functions used here take a boolean argument, others take a
+status argument. This breaks KCFI type checking, so clang now warns about
+the function pointer cast:
+
+drivers/scsi/bfa/bfad_bsg.c:2138:29: error: cast from 'void (*)(void *, enum bfa_status)' to 'bfa_cb_cbfn_t' (aka 'void (*)(void *, enum bfa_boolean)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+
+Assuming the code is actually correct here and the callers always match the
+argument types of the callee, rework this to replace the explicit cast with
+a union of the two pointer types. This does not change the behavior of the
+code, so if something is actually broken here, a larger rework may be
+necessary.
+
+Fixes: 37ea0558b87a ("[SCSI] bfa: Added support to collect and reset fcport stats")
+Fixes: 3ec4f2c8bff2 ("[SCSI] bfa: Added support to configure QOS and collect stats.")
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20240222124433.2046570-1-arnd@kernel.org
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/bfa/bfa.h | 9 ++++++++-
+ drivers/scsi/bfa/bfa_core.c | 4 +---
+ drivers/scsi/bfa/bfa_ioc.h | 8 ++++++--
+ drivers/scsi/bfa/bfad_bsg.c | 11 ++++-------
+ 4 files changed, 19 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/scsi/bfa/bfa.h b/drivers/scsi/bfa/bfa.h
+index 7bd2ba1ad4d11..f30fe324e6ecc 100644
+--- a/drivers/scsi/bfa/bfa.h
++++ b/drivers/scsi/bfa/bfa.h
+@@ -20,7 +20,6 @@
+ struct bfa_s;
+
+ typedef void (*bfa_isr_func_t) (struct bfa_s *bfa, struct bfi_msg_s *m);
+-typedef void (*bfa_cb_cbfn_status_t) (void *cbarg, bfa_status_t status);
+
+ /*
+ * Interrupt message handlers
+@@ -437,4 +436,12 @@ struct bfa_cb_pending_q_s {
+ (__qe)->data = (__data); \
+ } while (0)
+
++#define bfa_pending_q_init_status(__qe, __cbfn, __cbarg, __data) do { \
++ bfa_q_qe_init(&((__qe)->hcb_qe.qe)); \
++ (__qe)->hcb_qe.cbfn_status = (__cbfn); \
++ (__qe)->hcb_qe.cbarg = (__cbarg); \
++ (__qe)->hcb_qe.pre_rmv = BFA_TRUE; \
++ (__qe)->data = (__data); \
++} while (0)
++
+ #endif /* __BFA_H__ */
+diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c
+index 6846ca8f7313c..3438d0b8ba062 100644
+--- a/drivers/scsi/bfa/bfa_core.c
++++ b/drivers/scsi/bfa/bfa_core.c
+@@ -1907,15 +1907,13 @@ bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q)
+ struct list_head *qe;
+ struct list_head *qen;
+ struct bfa_cb_qe_s *hcb_qe;
+- bfa_cb_cbfn_status_t cbfn;
+
+ list_for_each_safe(qe, qen, comp_q) {
+ hcb_qe = (struct bfa_cb_qe_s *) qe;
+ if (hcb_qe->pre_rmv) {
+ /* qe is invalid after return, dequeue before cbfn() */
+ list_del(qe);
+- cbfn = (bfa_cb_cbfn_status_t)(hcb_qe->cbfn);
+- cbfn(hcb_qe->cbarg, hcb_qe->fw_status);
++ hcb_qe->cbfn_status(hcb_qe->cbarg, hcb_qe->fw_status);
+ } else
+ hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE);
+ }
+diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h
+index 933a1c3890ff5..5e568d6d7b261 100644
+--- a/drivers/scsi/bfa/bfa_ioc.h
++++ b/drivers/scsi/bfa/bfa_ioc.h
+@@ -361,14 +361,18 @@ struct bfa_reqq_wait_s {
+ void *cbarg;
+ };
+
+-typedef void (*bfa_cb_cbfn_t) (void *cbarg, bfa_boolean_t complete);
++typedef void (*bfa_cb_cbfn_t) (void *cbarg, bfa_boolean_t complete);
++typedef void (*bfa_cb_cbfn_status_t) (void *cbarg, bfa_status_t status);
+
+ /*
+ * Generic BFA callback element.
+ */
+ struct bfa_cb_qe_s {
+ struct list_head qe;
+- bfa_cb_cbfn_t cbfn;
++ union {
++ bfa_cb_cbfn_status_t cbfn_status;
++ bfa_cb_cbfn_t cbfn;
++ };
+ bfa_boolean_t once;
+ bfa_boolean_t pre_rmv; /* set for stack based qe(s) */
+ bfa_status_t fw_status; /* to access fw status in comp proc */
+diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
+index be8dfbe13e904..524e4e6979c9f 100644
+--- a/drivers/scsi/bfa/bfad_bsg.c
++++ b/drivers/scsi/bfa/bfad_bsg.c
+@@ -2135,8 +2135,7 @@ bfad_iocmd_fcport_get_stats(struct bfad_s *bfad, void *cmd)
+ struct bfa_cb_pending_q_s cb_qe;
+
+ init_completion(&fcomp.comp);
+- bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp,
+- &fcomp, &iocmd->stats);
++ bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, &iocmd->stats);
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe);
+ spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+@@ -2159,7 +2158,7 @@ bfad_iocmd_fcport_reset_stats(struct bfad_s *bfad, void *cmd)
+ struct bfa_cb_pending_q_s cb_qe;
+
+ init_completion(&fcomp.comp);
+- bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, &fcomp, NULL);
++ bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, NULL);
+
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe);
+@@ -2443,8 +2442,7 @@ bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd)
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
+
+ init_completion(&fcomp.comp);
+- bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp,
+- &fcomp, &iocmd->stats);
++ bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, &iocmd->stats);
+
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc));
+@@ -2474,8 +2472,7 @@ bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd)
+ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
+
+ init_completion(&fcomp.comp);
+- bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp,
+- &fcomp, NULL);
++ bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, NULL);
+
+ spin_lock_irqsave(&bfad->bfad_lock, flags);
+ WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc));
+--
+2.43.0
+
--- /dev/null
+From 5f44a507107fe22d88827b892ac598f1e2d0894c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Feb 2024 11:05:00 +0100
+Subject: scsi: csiostor: Avoid function pointer casts
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 9f3dbcb5632d6876226031d552ef6163bb3ad215 ]
+
+csiostor uses function pointer casts to keep the csio_ln_ev state machine
+hidden, but this causes warnings about control flow integrity (KCFI)
+violations in clang-16 and higher:
+
+drivers/scsi/csiostor/csio_lnode.c:1098:33: error: cast from 'void (*)(struct csio_lnode *, enum csio_ln_ev)' to 'csio_sm_state_t' (aka 'void (*)(void *, unsigned int)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+ 1098 | return (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_ready));
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+drivers/scsi/csiostor/csio_lnode.c:1369:29: error: cast from 'void (*)(struct csio_lnode *, enum csio_ln_ev)' to 'csio_sm_state_t' (aka 'void (*)(void *, unsigned int)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+ 1369 | if (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_uninit)) {
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+drivers/scsi/csiostor/csio_lnode.c:1373:29: error: cast from 'void (*)(struct csio_lnode *, enum csio_ln_ev)' to 'csio_sm_state_t' (aka 'void (*)(void *, unsigned int)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+ 1373 | if (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_ready)) {
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+drivers/scsi/csiostor/csio_lnode.c:1377:29: error: cast from 'void (*)(struct csio_lnode *, enum csio_ln_ev)' to 'csio_sm_state_t' (aka 'void (*)(void *, unsigned int)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+ 1377 | if (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_offline)) {
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Move the enum into a shared header so the correct types can be used without
+the need for casts.
+
+Fixes: a3667aaed569 ("[SCSI] csiostor: Chelsio FCoE offload driver")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20240213100518.457623-1-arnd@kernel.org
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/csiostor/csio_defs.h | 18 ++++++++++++++++--
+ drivers/scsi/csiostor/csio_lnode.c | 8 ++++----
+ drivers/scsi/csiostor/csio_lnode.h | 13 -------------
+ 3 files changed, 20 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/scsi/csiostor/csio_defs.h b/drivers/scsi/csiostor/csio_defs.h
+index c38017b4af982..e50e93e7fe5a1 100644
+--- a/drivers/scsi/csiostor/csio_defs.h
++++ b/drivers/scsi/csiostor/csio_defs.h
+@@ -73,7 +73,21 @@ csio_list_deleted(struct list_head *list)
+ #define csio_list_prev(elem) (((struct list_head *)(elem))->prev)
+
+ /* State machine */
+-typedef void (*csio_sm_state_t)(void *, uint32_t);
++struct csio_lnode;
++
++/* State machine evets */
++enum csio_ln_ev {
++ CSIO_LNE_NONE = (uint32_t)0,
++ CSIO_LNE_LINKUP,
++ CSIO_LNE_FAB_INIT_DONE,
++ CSIO_LNE_LINK_DOWN,
++ CSIO_LNE_DOWN_LINK,
++ CSIO_LNE_LOGO,
++ CSIO_LNE_CLOSE,
++ CSIO_LNE_MAX_EVENT,
++};
++
++typedef void (*csio_sm_state_t)(struct csio_lnode *ln, enum csio_ln_ev evt);
+
+ struct csio_sm {
+ struct list_head sm_list;
+@@ -83,7 +97,7 @@ struct csio_sm {
+ static inline void
+ csio_set_state(void *smp, void *state)
+ {
+- ((struct csio_sm *)smp)->sm_state = (csio_sm_state_t)state;
++ ((struct csio_sm *)smp)->sm_state = state;
+ }
+
+ static inline void
+diff --git a/drivers/scsi/csiostor/csio_lnode.c b/drivers/scsi/csiostor/csio_lnode.c
+index d5ac938970232..5b3ffefae476d 100644
+--- a/drivers/scsi/csiostor/csio_lnode.c
++++ b/drivers/scsi/csiostor/csio_lnode.c
+@@ -1095,7 +1095,7 @@ csio_handle_link_down(struct csio_hw *hw, uint8_t portid, uint32_t fcfi,
+ int
+ csio_is_lnode_ready(struct csio_lnode *ln)
+ {
+- return (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_ready));
++ return (csio_get_state(ln) == csio_lns_ready);
+ }
+
+ /*****************************************************************************/
+@@ -1366,15 +1366,15 @@ csio_free_fcfinfo(struct kref *kref)
+ void
+ csio_lnode_state_to_str(struct csio_lnode *ln, int8_t *str)
+ {
+- if (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_uninit)) {
++ if (csio_get_state(ln) == csio_lns_uninit) {
+ strcpy(str, "UNINIT");
+ return;
+ }
+- if (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_ready)) {
++ if (csio_get_state(ln) == csio_lns_ready) {
+ strcpy(str, "READY");
+ return;
+ }
+- if (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_offline)) {
++ if (csio_get_state(ln) == csio_lns_offline) {
+ strcpy(str, "OFFLINE");
+ return;
+ }
+diff --git a/drivers/scsi/csiostor/csio_lnode.h b/drivers/scsi/csiostor/csio_lnode.h
+index 372a67d122d38..607698a0f0631 100644
+--- a/drivers/scsi/csiostor/csio_lnode.h
++++ b/drivers/scsi/csiostor/csio_lnode.h
+@@ -53,19 +53,6 @@
+ extern int csio_fcoe_rnodes;
+ extern int csio_fdmi_enable;
+
+-/* State machine evets */
+-enum csio_ln_ev {
+- CSIO_LNE_NONE = (uint32_t)0,
+- CSIO_LNE_LINKUP,
+- CSIO_LNE_FAB_INIT_DONE,
+- CSIO_LNE_LINK_DOWN,
+- CSIO_LNE_DOWN_LINK,
+- CSIO_LNE_LOGO,
+- CSIO_LNE_CLOSE,
+- CSIO_LNE_MAX_EVENT,
+-};
+-
+-
+ struct csio_fcf_info {
+ struct list_head list;
+ uint8_t priority;
+--
+2.43.0
+
--- /dev/null
+From 129147a9c5a9b8863d216429d492d65b7d6e2302 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 16:06:19 +0300
+Subject: selftest/bpf: Add map_in_maps with BPF_MAP_TYPE_PERF_EVENT_ARRAY
+ values
+
+From: Andrey Grafin <conquistador@yandex-team.ru>
+
+[ Upstream commit 40628f9fff73adecac77a9aa390f8016724cad99 ]
+
+Check that bpf_object__load() successfully creates map_in_maps
+with BPF_MAP_TYPE_PERF_EVENT_ARRAY values.
+These changes cover fix in the previous patch
+"libbpf: Apply map_set_def_max_entries() for inner_maps on creation".
+
+A command line output is:
+- w/o fix
+$ sudo ./test_maps
+libbpf: map 'mim_array_pe': failed to create inner map: -22
+libbpf: map 'mim_array_pe': failed to create: Invalid argument(-22)
+libbpf: failed to load object './test_map_in_map.bpf.o'
+Failed to load test prog
+
+- with fix
+$ sudo ./test_maps
+...
+test_maps: OK, 0 SKIPPED
+
+Fixes: 646f02ffdd49 ("libbpf: Add BTF-defined map-in-map support")
+Signed-off-by: Andrey Grafin <conquistador@yandex-team.ru>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Yonghong Song <yonghong.song@linux.dev>
+Acked-by: Hou Tao <houtao1@huawei.com>
+Link: https://lore.kernel.org/bpf/20240117130619.9403-2-conquistador@yandex-team.ru
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/bpf/progs/test_map_in_map.c | 26 +++++++++++++++++++
+ tools/testing/selftests/bpf/test_maps.c | 6 ++++-
+ 2 files changed, 31 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/bpf/progs/test_map_in_map.c b/tools/testing/selftests/bpf/progs/test_map_in_map.c
+index f416032ba858b..b295f9b721bf8 100644
+--- a/tools/testing/selftests/bpf/progs/test_map_in_map.c
++++ b/tools/testing/selftests/bpf/progs/test_map_in_map.c
+@@ -21,6 +21,32 @@ struct {
+ __type(value, __u32);
+ } mim_hash SEC(".maps");
+
++/* The following three maps are used to test
++ * perf_event_array map can be an inner
++ * map of hash/array_of_maps.
++ */
++struct perf_event_array {
++ __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
++ __type(key, __u32);
++ __type(value, __u32);
++} inner_map0 SEC(".maps");
++
++struct {
++ __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
++ __uint(max_entries, 1);
++ __type(key, __u32);
++ __array(values, struct perf_event_array);
++} mim_array_pe SEC(".maps") = {
++ .values = {&inner_map0}};
++
++struct {
++ __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS);
++ __uint(max_entries, 1);
++ __type(key, __u32);
++ __array(values, struct perf_event_array);
++} mim_hash_pe SEC(".maps") = {
++ .values = {&inner_map0}};
++
+ SEC("xdp")
+ int xdp_mimtest0(struct xdp_md *ctx)
+ {
+diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c
+index b73152822aa28..81cd48cc80c23 100644
+--- a/tools/testing/selftests/bpf/test_maps.c
++++ b/tools/testing/selftests/bpf/test_maps.c
+@@ -1190,7 +1190,11 @@ static void test_map_in_map(void)
+ goto out_map_in_map;
+ }
+
+- bpf_object__load(obj);
++ err = bpf_object__load(obj);
++ if (err) {
++ printf("Failed to load test prog\n");
++ goto out_map_in_map;
++ }
+
+ map = bpf_object__find_map_by_name(obj, "mim_array");
+ if (!map) {
+--
+2.43.0
+
--- /dev/null
+From 265e24f101bcbe1b11579d24363f7bb3b8f6f81c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Feb 2023 20:59:54 -0800
+Subject: selftests/bpf: Add global subprog context passing tests
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit e2b5cfc978f871996d1f8667515c0e06b33e620e ]
+
+Add tests validating that it's possible to pass context arguments into
+global subprogs for various types of programs, including a particularly
+tricky KPROBE programs (which cover kprobes, uprobes, USDTs, a vast and
+important class of programs).
+
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Stanislav Fomichev <sdf@google.com>
+Link: https://lore.kernel.org/bpf/20230216045954.3002473-4-andrii@kernel.org
+Stable-dep-of: 879bbe7aa4af ("bpf: don't infer PTR_TO_CTX for programs with unnamed context type")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../bpf/prog_tests/test_global_funcs.c | 2 +
+ .../bpf/progs/test_global_func_ctx_args.c | 104 ++++++++++++++++++
+ 2 files changed, 106 insertions(+)
+ create mode 100644 tools/testing/selftests/bpf/progs/test_global_func_ctx_args.c
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c b/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c
+index 2ff4d5c7abfce..e0879df38639b 100644
+--- a/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c
++++ b/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c
+@@ -18,6 +18,7 @@
+ #include "test_global_func15.skel.h"
+ #include "test_global_func16.skel.h"
+ #include "test_global_func17.skel.h"
++#include "test_global_func_ctx_args.skel.h"
+
+ void test_test_global_funcs(void)
+ {
+@@ -38,4 +39,5 @@ void test_test_global_funcs(void)
+ RUN_TESTS(test_global_func15);
+ RUN_TESTS(test_global_func16);
+ RUN_TESTS(test_global_func17);
++ RUN_TESTS(test_global_func_ctx_args);
+ }
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func_ctx_args.c b/tools/testing/selftests/bpf/progs/test_global_func_ctx_args.c
+new file mode 100644
+index 0000000000000..7faa8eef0598b
+--- /dev/null
++++ b/tools/testing/selftests/bpf/progs/test_global_func_ctx_args.c
+@@ -0,0 +1,104 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
++#include "vmlinux.h"
++#include <bpf/bpf_helpers.h>
++#include <bpf/bpf_tracing.h>
++#include <bpf/bpf_core_read.h>
++#include "bpf_misc.h"
++
++char _license[] SEC("license") = "GPL";
++
++static long stack[256];
++
++/*
++ * KPROBE contexts
++ */
++
++__weak int kprobe_typedef_ctx_subprog(bpf_user_pt_regs_t *ctx)
++{
++ return bpf_get_stack(ctx, &stack, sizeof(stack), 0);
++}
++
++SEC("?kprobe")
++__success
++int kprobe_typedef_ctx(void *ctx)
++{
++ return kprobe_typedef_ctx_subprog(ctx);
++}
++
++#define pt_regs_struct_t typeof(*(__PT_REGS_CAST((struct pt_regs *)NULL)))
++
++__weak int kprobe_struct_ctx_subprog(pt_regs_struct_t *ctx)
++{
++ return bpf_get_stack((void *)ctx, &stack, sizeof(stack), 0);
++}
++
++SEC("?kprobe")
++__success
++int kprobe_resolved_ctx(void *ctx)
++{
++ return kprobe_struct_ctx_subprog(ctx);
++}
++
++/* this is current hack to make this work on old kernels */
++struct bpf_user_pt_regs_t {};
++
++__weak int kprobe_workaround_ctx_subprog(struct bpf_user_pt_regs_t *ctx)
++{
++ return bpf_get_stack(ctx, &stack, sizeof(stack), 0);
++}
++
++SEC("?kprobe")
++__success
++int kprobe_workaround_ctx(void *ctx)
++{
++ return kprobe_workaround_ctx_subprog(ctx);
++}
++
++/*
++ * RAW_TRACEPOINT contexts
++ */
++
++__weak int raw_tp_ctx_subprog(struct bpf_raw_tracepoint_args *ctx)
++{
++ return bpf_get_stack(ctx, &stack, sizeof(stack), 0);
++}
++
++SEC("?raw_tp")
++__success
++int raw_tp_ctx(void *ctx)
++{
++ return raw_tp_ctx_subprog(ctx);
++}
++
++/*
++ * RAW_TRACEPOINT_WRITABLE contexts
++ */
++
++__weak int raw_tp_writable_ctx_subprog(struct bpf_raw_tracepoint_args *ctx)
++{
++ return bpf_get_stack(ctx, &stack, sizeof(stack), 0);
++}
++
++SEC("?raw_tp")
++__success
++int raw_tp_writable_ctx(void *ctx)
++{
++ return raw_tp_writable_ctx_subprog(ctx);
++}
++
++/*
++ * PERF_EVENT contexts
++ */
++
++__weak int perf_event_ctx_subprog(struct bpf_perf_event_data *ctx)
++{
++ return bpf_get_stack(ctx, &stack, sizeof(stack), 0);
++}
++
++SEC("?perf_event")
++__success
++int perf_event_ctx(void *ctx)
++{
++ return perf_event_ctx_subprog(ctx);
++}
+--
+2.43.0
+
--- /dev/null
+From 0e138c9aba7500555af6dee0d2a3dc48ced1c11c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 Feb 2023 20:59:53 -0800
+Subject: selftests/bpf: Convert test_global_funcs test to test_loader
+ framework
+
+From: Andrii Nakryiko <andrii@kernel.org>
+
+[ Upstream commit 95ebb376176c52382293e05e63f142114a5e40ef ]
+
+Convert 17 test_global_funcs subtests into test_loader framework for
+easier maintenance and more declarative way to define expected
+failures/successes.
+
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Stanislav Fomichev <sdf@google.com>
+Link: https://lore.kernel.org/bpf/20230216045954.3002473-3-andrii@kernel.org
+Stable-dep-of: 879bbe7aa4af ("bpf: don't infer PTR_TO_CTX for programs with unnamed context type")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../bpf/prog_tests/test_global_funcs.c | 131 +++++-------------
+ .../selftests/bpf/progs/test_global_func1.c | 6 +-
+ .../selftests/bpf/progs/test_global_func10.c | 4 +-
+ .../selftests/bpf/progs/test_global_func11.c | 4 +-
+ .../selftests/bpf/progs/test_global_func12.c | 4 +-
+ .../selftests/bpf/progs/test_global_func13.c | 4 +-
+ .../selftests/bpf/progs/test_global_func14.c | 4 +-
+ .../selftests/bpf/progs/test_global_func15.c | 4 +-
+ .../selftests/bpf/progs/test_global_func16.c | 4 +-
+ .../selftests/bpf/progs/test_global_func17.c | 4 +-
+ .../selftests/bpf/progs/test_global_func2.c | 43 +++++-
+ .../selftests/bpf/progs/test_global_func3.c | 10 +-
+ .../selftests/bpf/progs/test_global_func4.c | 55 +++++++-
+ .../selftests/bpf/progs/test_global_func5.c | 4 +-
+ .../selftests/bpf/progs/test_global_func6.c | 4 +-
+ .../selftests/bpf/progs/test_global_func7.c | 4 +-
+ .../selftests/bpf/progs/test_global_func8.c | 4 +-
+ .../selftests/bpf/progs/test_global_func9.c | 4 +-
+ 18 files changed, 174 insertions(+), 123 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c b/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c
+index 7295cc60f7248..2ff4d5c7abfce 100644
+--- a/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c
++++ b/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c
+@@ -1,104 +1,41 @@
+ // SPDX-License-Identifier: GPL-2.0
+ /* Copyright (c) 2020 Facebook */
+ #include <test_progs.h>
+-
+-const char *err_str;
+-bool found;
+-
+-static int libbpf_debug_print(enum libbpf_print_level level,
+- const char *format, va_list args)
+-{
+- char *log_buf;
+-
+- if (level != LIBBPF_WARN ||
+- strcmp(format, "libbpf: \n%s\n")) {
+- vprintf(format, args);
+- return 0;
+- }
+-
+- log_buf = va_arg(args, char *);
+- if (!log_buf)
+- goto out;
+- if (err_str && strstr(log_buf, err_str) == 0)
+- found = true;
+-out:
+- printf(format, log_buf);
+- return 0;
+-}
+-
+-extern int extra_prog_load_log_flags;
+-
+-static int check_load(const char *file)
+-{
+- struct bpf_object *obj = NULL;
+- struct bpf_program *prog;
+- int err;
+-
+- found = false;
+-
+- obj = bpf_object__open_file(file, NULL);
+- err = libbpf_get_error(obj);
+- if (err)
+- return err;
+-
+- prog = bpf_object__next_program(obj, NULL);
+- if (!prog) {
+- err = -ENOENT;
+- goto err_out;
+- }
+-
+- bpf_program__set_flags(prog, BPF_F_TEST_RND_HI32);
+- bpf_program__set_log_level(prog, extra_prog_load_log_flags);
+-
+- err = bpf_object__load(obj);
+-
+-err_out:
+- bpf_object__close(obj);
+- return err;
+-}
+-
+-struct test_def {
+- const char *file;
+- const char *err_str;
+-};
++#include "test_global_func1.skel.h"
++#include "test_global_func2.skel.h"
++#include "test_global_func3.skel.h"
++#include "test_global_func4.skel.h"
++#include "test_global_func5.skel.h"
++#include "test_global_func6.skel.h"
++#include "test_global_func7.skel.h"
++#include "test_global_func8.skel.h"
++#include "test_global_func9.skel.h"
++#include "test_global_func10.skel.h"
++#include "test_global_func11.skel.h"
++#include "test_global_func12.skel.h"
++#include "test_global_func13.skel.h"
++#include "test_global_func14.skel.h"
++#include "test_global_func15.skel.h"
++#include "test_global_func16.skel.h"
++#include "test_global_func17.skel.h"
+
+ void test_test_global_funcs(void)
+ {
+- struct test_def tests[] = {
+- { "test_global_func1.bpf.o", "combined stack size of 4 calls is 544" },
+- { "test_global_func2.bpf.o" },
+- { "test_global_func3.bpf.o", "the call stack of 8 frames" },
+- { "test_global_func4.bpf.o" },
+- { "test_global_func5.bpf.o", "expected pointer to ctx, but got PTR" },
+- { "test_global_func6.bpf.o", "modified ctx ptr R2" },
+- { "test_global_func7.bpf.o", "foo() doesn't return scalar" },
+- { "test_global_func8.bpf.o" },
+- { "test_global_func9.bpf.o" },
+- { "test_global_func10.bpf.o", "invalid indirect read from stack" },
+- { "test_global_func11.bpf.o", "Caller passes invalid args into func#1" },
+- { "test_global_func12.bpf.o", "invalid mem access 'mem_or_null'" },
+- { "test_global_func13.bpf.o", "Caller passes invalid args into func#1" },
+- { "test_global_func14.bpf.o", "reference type('FWD S') size cannot be determined" },
+- { "test_global_func15.bpf.o", "At program exit the register R0 has value" },
+- { "test_global_func16.bpf.o", "invalid indirect read from stack" },
+- { "test_global_func17.bpf.o", "Caller passes invalid args into func#1" },
+- };
+- libbpf_print_fn_t old_print_fn = NULL;
+- int err, i, duration = 0;
+-
+- old_print_fn = libbpf_set_print(libbpf_debug_print);
+-
+- for (i = 0; i < ARRAY_SIZE(tests); i++) {
+- const struct test_def *test = &tests[i];
+-
+- if (!test__start_subtest(test->file))
+- continue;
+-
+- err_str = test->err_str;
+- err = check_load(test->file);
+- CHECK_FAIL(!!err ^ !!err_str);
+- if (err_str)
+- CHECK(found, "", "expected string '%s'", err_str);
+- }
+- libbpf_set_print(old_print_fn);
++ RUN_TESTS(test_global_func1);
++ RUN_TESTS(test_global_func2);
++ RUN_TESTS(test_global_func3);
++ RUN_TESTS(test_global_func4);
++ RUN_TESTS(test_global_func5);
++ RUN_TESTS(test_global_func6);
++ RUN_TESTS(test_global_func7);
++ RUN_TESTS(test_global_func8);
++ RUN_TESTS(test_global_func9);
++ RUN_TESTS(test_global_func10);
++ RUN_TESTS(test_global_func11);
++ RUN_TESTS(test_global_func12);
++ RUN_TESTS(test_global_func13);
++ RUN_TESTS(test_global_func14);
++ RUN_TESTS(test_global_func15);
++ RUN_TESTS(test_global_func16);
++ RUN_TESTS(test_global_func17);
+ }
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func1.c b/tools/testing/selftests/bpf/progs/test_global_func1.c
+index 7b42dad187b89..23970a20b3249 100644
+--- a/tools/testing/selftests/bpf/progs/test_global_func1.c
++++ b/tools/testing/selftests/bpf/progs/test_global_func1.c
+@@ -3,10 +3,9 @@
+ #include <stddef.h>
+ #include <linux/bpf.h>
+ #include <bpf/bpf_helpers.h>
++#include "bpf_misc.h"
+
+-#ifndef MAX_STACK
+ #define MAX_STACK (512 - 3 * 32 + 8)
+-#endif
+
+ static __attribute__ ((noinline))
+ int f0(int var, struct __sk_buff *skb)
+@@ -39,7 +38,8 @@ int f3(int val, struct __sk_buff *skb, int var)
+ }
+
+ SEC("tc")
+-int test_cls(struct __sk_buff *skb)
++__failure __msg("combined stack size of 4 calls is 544")
++int global_func1(struct __sk_buff *skb)
+ {
+ return f0(1, skb) + f1(skb) + f2(2, skb) + f3(3, skb, 4);
+ }
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func10.c b/tools/testing/selftests/bpf/progs/test_global_func10.c
+index 97b7031d0e227..98327bdbbfd24 100644
+--- a/tools/testing/selftests/bpf/progs/test_global_func10.c
++++ b/tools/testing/selftests/bpf/progs/test_global_func10.c
+@@ -2,6 +2,7 @@
+ #include <stddef.h>
+ #include <linux/bpf.h>
+ #include <bpf/bpf_helpers.h>
++#include "bpf_misc.h"
+
+ struct Small {
+ int x;
+@@ -21,7 +22,8 @@ __noinline int foo(const struct Big *big)
+ }
+
+ SEC("cgroup_skb/ingress")
+-int test_cls(struct __sk_buff *skb)
++__failure __msg("invalid indirect read from stack")
++int global_func10(struct __sk_buff *skb)
+ {
+ const struct Small small = {.x = skb->len };
+
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func11.c b/tools/testing/selftests/bpf/progs/test_global_func11.c
+index ef5277d982d92..283e036dc401e 100644
+--- a/tools/testing/selftests/bpf/progs/test_global_func11.c
++++ b/tools/testing/selftests/bpf/progs/test_global_func11.c
+@@ -2,6 +2,7 @@
+ #include <stddef.h>
+ #include <linux/bpf.h>
+ #include <bpf/bpf_helpers.h>
++#include "bpf_misc.h"
+
+ struct S {
+ int x;
+@@ -13,7 +14,8 @@ __noinline int foo(const struct S *s)
+ }
+
+ SEC("cgroup_skb/ingress")
+-int test_cls(struct __sk_buff *skb)
++__failure __msg("Caller passes invalid args into func#1")
++int global_func11(struct __sk_buff *skb)
+ {
+ return foo((const void *)skb);
+ }
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func12.c b/tools/testing/selftests/bpf/progs/test_global_func12.c
+index 62343527cc598..7f159d83c6f67 100644
+--- a/tools/testing/selftests/bpf/progs/test_global_func12.c
++++ b/tools/testing/selftests/bpf/progs/test_global_func12.c
+@@ -2,6 +2,7 @@
+ #include <stddef.h>
+ #include <linux/bpf.h>
+ #include <bpf/bpf_helpers.h>
++#include "bpf_misc.h"
+
+ struct S {
+ int x;
+@@ -13,7 +14,8 @@ __noinline int foo(const struct S *s)
+ }
+
+ SEC("cgroup_skb/ingress")
+-int test_cls(struct __sk_buff *skb)
++__failure __msg("invalid mem access 'mem_or_null'")
++int global_func12(struct __sk_buff *skb)
+ {
+ const struct S s = {.x = skb->len };
+
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func13.c b/tools/testing/selftests/bpf/progs/test_global_func13.c
+index ff8897c1ac22b..02ea80da75b57 100644
+--- a/tools/testing/selftests/bpf/progs/test_global_func13.c
++++ b/tools/testing/selftests/bpf/progs/test_global_func13.c
+@@ -2,6 +2,7 @@
+ #include <stddef.h>
+ #include <linux/bpf.h>
+ #include <bpf/bpf_helpers.h>
++#include "bpf_misc.h"
+
+ struct S {
+ int x;
+@@ -16,7 +17,8 @@ __noinline int foo(const struct S *s)
+ }
+
+ SEC("cgroup_skb/ingress")
+-int test_cls(struct __sk_buff *skb)
++__failure __msg("Caller passes invalid args into func#1")
++int global_func13(struct __sk_buff *skb)
+ {
+ const struct S *s = (const struct S *)(0xbedabeda);
+
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func14.c b/tools/testing/selftests/bpf/progs/test_global_func14.c
+index 698c77199ebf7..33b7d5efd7b26 100644
+--- a/tools/testing/selftests/bpf/progs/test_global_func14.c
++++ b/tools/testing/selftests/bpf/progs/test_global_func14.c
+@@ -2,6 +2,7 @@
+ #include <stddef.h>
+ #include <linux/bpf.h>
+ #include <bpf/bpf_helpers.h>
++#include "bpf_misc.h"
+
+ struct S;
+
+@@ -14,7 +15,8 @@ __noinline int foo(const struct S *s)
+ }
+
+ SEC("cgroup_skb/ingress")
+-int test_cls(struct __sk_buff *skb)
++__failure __msg("reference type('FWD S') size cannot be determined")
++int global_func14(struct __sk_buff *skb)
+ {
+
+ return foo(NULL);
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func15.c b/tools/testing/selftests/bpf/progs/test_global_func15.c
+index c19c435988d55..b512d6a6c75e5 100644
+--- a/tools/testing/selftests/bpf/progs/test_global_func15.c
++++ b/tools/testing/selftests/bpf/progs/test_global_func15.c
+@@ -2,6 +2,7 @@
+ #include <stddef.h>
+ #include <linux/bpf.h>
+ #include <bpf/bpf_helpers.h>
++#include "bpf_misc.h"
+
+ __noinline int foo(unsigned int *v)
+ {
+@@ -12,7 +13,8 @@ __noinline int foo(unsigned int *v)
+ }
+
+ SEC("cgroup_skb/ingress")
+-int test_cls(struct __sk_buff *skb)
++__failure __msg("At program exit the register R0 has value")
++int global_func15(struct __sk_buff *skb)
+ {
+ unsigned int v = 1;
+
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func16.c b/tools/testing/selftests/bpf/progs/test_global_func16.c
+index 0312d1e8d8c06..e7206304632e1 100644
+--- a/tools/testing/selftests/bpf/progs/test_global_func16.c
++++ b/tools/testing/selftests/bpf/progs/test_global_func16.c
+@@ -2,6 +2,7 @@
+ #include <stddef.h>
+ #include <linux/bpf.h>
+ #include <bpf/bpf_helpers.h>
++#include "bpf_misc.h"
+
+ __noinline int foo(int (*arr)[10])
+ {
+@@ -12,7 +13,8 @@ __noinline int foo(int (*arr)[10])
+ }
+
+ SEC("cgroup_skb/ingress")
+-int test_cls(struct __sk_buff *skb)
++__failure __msg("invalid indirect read from stack")
++int global_func16(struct __sk_buff *skb)
+ {
+ int array[10];
+
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func17.c b/tools/testing/selftests/bpf/progs/test_global_func17.c
+index 2b8b9b8ba0183..a32e11c7d933e 100644
+--- a/tools/testing/selftests/bpf/progs/test_global_func17.c
++++ b/tools/testing/selftests/bpf/progs/test_global_func17.c
+@@ -1,6 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+ #include <vmlinux.h>
+ #include <bpf/bpf_helpers.h>
++#include "bpf_misc.h"
+
+ __noinline int foo(int *p)
+ {
+@@ -10,7 +11,8 @@ __noinline int foo(int *p)
+ const volatile int i;
+
+ SEC("tc")
+-int test_cls(struct __sk_buff *skb)
++__failure __msg("Caller passes invalid args into func#1")
++int global_func17(struct __sk_buff *skb)
+ {
+ return foo((int *)&i);
+ }
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func2.c b/tools/testing/selftests/bpf/progs/test_global_func2.c
+index 2c18d82923a2d..3dce97fb52a4b 100644
+--- a/tools/testing/selftests/bpf/progs/test_global_func2.c
++++ b/tools/testing/selftests/bpf/progs/test_global_func2.c
+@@ -1,4 +1,45 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+ /* Copyright (c) 2020 Facebook */
++#include <stddef.h>
++#include <linux/bpf.h>
++#include <bpf/bpf_helpers.h>
++#include "bpf_misc.h"
++
+ #define MAX_STACK (512 - 3 * 32)
+-#include "test_global_func1.c"
++
++static __attribute__ ((noinline))
++int f0(int var, struct __sk_buff *skb)
++{
++ return skb->len;
++}
++
++__attribute__ ((noinline))
++int f1(struct __sk_buff *skb)
++{
++ volatile char buf[MAX_STACK] = {};
++
++ return f0(0, skb) + skb->len;
++}
++
++int f3(int, struct __sk_buff *skb, int);
++
++__attribute__ ((noinline))
++int f2(int val, struct __sk_buff *skb)
++{
++ return f1(skb) + f3(val, skb, 1);
++}
++
++__attribute__ ((noinline))
++int f3(int val, struct __sk_buff *skb, int var)
++{
++ volatile char buf[MAX_STACK] = {};
++
++ return skb->ifindex * val * var;
++}
++
++SEC("tc")
++__success
++int global_func2(struct __sk_buff *skb)
++{
++ return f0(1, skb) + f1(skb) + f2(2, skb) + f3(3, skb, 4);
++}
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func3.c b/tools/testing/selftests/bpf/progs/test_global_func3.c
+index 01bf8275dfd64..142b682d3c2f0 100644
+--- a/tools/testing/selftests/bpf/progs/test_global_func3.c
++++ b/tools/testing/selftests/bpf/progs/test_global_func3.c
+@@ -3,6 +3,7 @@
+ #include <stddef.h>
+ #include <linux/bpf.h>
+ #include <bpf/bpf_helpers.h>
++#include "bpf_misc.h"
+
+ __attribute__ ((noinline))
+ int f1(struct __sk_buff *skb)
+@@ -46,20 +47,15 @@ int f7(struct __sk_buff *skb)
+ return f6(skb);
+ }
+
+-#ifndef NO_FN8
+ __attribute__ ((noinline))
+ int f8(struct __sk_buff *skb)
+ {
+ return f7(skb);
+ }
+-#endif
+
+ SEC("tc")
+-int test_cls(struct __sk_buff *skb)
++__failure __msg("the call stack of 8 frames")
++int global_func3(struct __sk_buff *skb)
+ {
+-#ifndef NO_FN8
+ return f8(skb);
+-#else
+- return f7(skb);
+-#endif
+ }
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func4.c b/tools/testing/selftests/bpf/progs/test_global_func4.c
+index 610f75edf2764..1733d87ad3f3e 100644
+--- a/tools/testing/selftests/bpf/progs/test_global_func4.c
++++ b/tools/testing/selftests/bpf/progs/test_global_func4.c
+@@ -1,4 +1,55 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+ /* Copyright (c) 2020 Facebook */
+-#define NO_FN8
+-#include "test_global_func3.c"
++#include <stddef.h>
++#include <linux/bpf.h>
++#include <bpf/bpf_helpers.h>
++#include "bpf_misc.h"
++
++__attribute__ ((noinline))
++int f1(struct __sk_buff *skb)
++{
++ return skb->len;
++}
++
++__attribute__ ((noinline))
++int f2(int val, struct __sk_buff *skb)
++{
++ return f1(skb) + val;
++}
++
++__attribute__ ((noinline))
++int f3(int val, struct __sk_buff *skb, int var)
++{
++ return f2(var, skb) + val;
++}
++
++__attribute__ ((noinline))
++int f4(struct __sk_buff *skb)
++{
++ return f3(1, skb, 2);
++}
++
++__attribute__ ((noinline))
++int f5(struct __sk_buff *skb)
++{
++ return f4(skb);
++}
++
++__attribute__ ((noinline))
++int f6(struct __sk_buff *skb)
++{
++ return f5(skb);
++}
++
++__attribute__ ((noinline))
++int f7(struct __sk_buff *skb)
++{
++ return f6(skb);
++}
++
++SEC("tc")
++__success
++int global_func4(struct __sk_buff *skb)
++{
++ return f7(skb);
++}
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func5.c b/tools/testing/selftests/bpf/progs/test_global_func5.c
+index 9248d03e0d06f..cc55aedaf82d5 100644
+--- a/tools/testing/selftests/bpf/progs/test_global_func5.c
++++ b/tools/testing/selftests/bpf/progs/test_global_func5.c
+@@ -3,6 +3,7 @@
+ #include <stddef.h>
+ #include <linux/bpf.h>
+ #include <bpf/bpf_helpers.h>
++#include "bpf_misc.h"
+
+ __attribute__ ((noinline))
+ int f1(struct __sk_buff *skb)
+@@ -25,7 +26,8 @@ int f3(int val, struct __sk_buff *skb)
+ }
+
+ SEC("tc")
+-int test_cls(struct __sk_buff *skb)
++__failure __msg("expected pointer to ctx, but got PTR")
++int global_func5(struct __sk_buff *skb)
+ {
+ return f1(skb) + f2(2, skb) + f3(3, skb);
+ }
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func6.c b/tools/testing/selftests/bpf/progs/test_global_func6.c
+index af8c78bdfb257..46c38c8f2cf03 100644
+--- a/tools/testing/selftests/bpf/progs/test_global_func6.c
++++ b/tools/testing/selftests/bpf/progs/test_global_func6.c
+@@ -3,6 +3,7 @@
+ #include <stddef.h>
+ #include <linux/bpf.h>
+ #include <bpf/bpf_helpers.h>
++#include "bpf_misc.h"
+
+ __attribute__ ((noinline))
+ int f1(struct __sk_buff *skb)
+@@ -25,7 +26,8 @@ int f3(int val, struct __sk_buff *skb)
+ }
+
+ SEC("tc")
+-int test_cls(struct __sk_buff *skb)
++__failure __msg("modified ctx ptr R2")
++int global_func6(struct __sk_buff *skb)
+ {
+ return f1(skb) + f2(2, skb) + f3(3, skb);
+ }
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func7.c b/tools/testing/selftests/bpf/progs/test_global_func7.c
+index 6cb8e2f5254cf..f182febfde3c0 100644
+--- a/tools/testing/selftests/bpf/progs/test_global_func7.c
++++ b/tools/testing/selftests/bpf/progs/test_global_func7.c
+@@ -3,6 +3,7 @@
+ #include <stddef.h>
+ #include <linux/bpf.h>
+ #include <bpf/bpf_helpers.h>
++#include "bpf_misc.h"
+
+ __attribute__ ((noinline))
+ void foo(struct __sk_buff *skb)
+@@ -11,7 +12,8 @@ void foo(struct __sk_buff *skb)
+ }
+
+ SEC("tc")
+-int test_cls(struct __sk_buff *skb)
++__failure __msg("foo() doesn't return scalar")
++int global_func7(struct __sk_buff *skb)
+ {
+ foo(skb);
+ return 0;
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func8.c b/tools/testing/selftests/bpf/progs/test_global_func8.c
+index d55a6544b1abd..9b9c57fa2dd34 100644
+--- a/tools/testing/selftests/bpf/progs/test_global_func8.c
++++ b/tools/testing/selftests/bpf/progs/test_global_func8.c
+@@ -3,6 +3,7 @@
+ #include <stddef.h>
+ #include <linux/bpf.h>
+ #include <bpf/bpf_helpers.h>
++#include "bpf_misc.h"
+
+ __noinline int foo(struct __sk_buff *skb)
+ {
+@@ -10,7 +11,8 @@ __noinline int foo(struct __sk_buff *skb)
+ }
+
+ SEC("cgroup_skb/ingress")
+-int test_cls(struct __sk_buff *skb)
++__success
++int global_func8(struct __sk_buff *skb)
+ {
+ if (!foo(skb))
+ return 0;
+diff --git a/tools/testing/selftests/bpf/progs/test_global_func9.c b/tools/testing/selftests/bpf/progs/test_global_func9.c
+index bd233ddede98a..1f2cb0159b8d8 100644
+--- a/tools/testing/selftests/bpf/progs/test_global_func9.c
++++ b/tools/testing/selftests/bpf/progs/test_global_func9.c
+@@ -2,6 +2,7 @@
+ #include <stddef.h>
+ #include <linux/bpf.h>
+ #include <bpf/bpf_helpers.h>
++#include "bpf_misc.h"
+
+ struct S {
+ int x;
+@@ -74,7 +75,8 @@ __noinline int quuz(int **p)
+ }
+
+ SEC("cgroup_skb/ingress")
+-int test_cls(struct __sk_buff *skb)
++__success
++int global_func9(struct __sk_buff *skb)
+ {
+ int result = 0;
+
+--
+2.43.0
+
--- /dev/null
+From 5f32c22b0e6942df147723ff432493294d6257db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Jan 2024 17:36:16 +0100
+Subject: selftests: forwarding: Add missing config entries
+
+From: Petr Machata <petrm@nvidia.com>
+
+[ Upstream commit 4acf4e62cd572b0c806035046b3698f5585ab821 ]
+
+The config file contains a partial kernel configuration to be used by
+`virtme-configkernel --custom'. The presumption is that the config file
+contains all Kconfig options needed by the selftests from the directory.
+
+In net/forwarding/config, many are missing, which manifests as spurious
+failures when running the selftests, with messages about unknown device
+types, qdisc kinds or classifier actions. Add the missing configurations.
+
+Tested the resulting configuration using virtme-ng as follows:
+
+ # vng -b -f tools/testing/selftests/net/forwarding/config
+ # vng --user root
+ (within the VM:)
+ # make -C tools/testing/selftests TARGETS=net/forwarding run_tests
+
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Link: https://lore.kernel.org/r/025abded7ff9cea5874a7fe35dcd3fd41bf5e6ac.1706286755.git.petrm@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: f0ddf15f0a74 ("selftests: forwarding: Add missing multicast routing config entries")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/config | 28 +++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/tools/testing/selftests/net/forwarding/config b/tools/testing/selftests/net/forwarding/config
+index 697994a9278bb..ba23435145827 100644
+--- a/tools/testing/selftests/net/forwarding/config
++++ b/tools/testing/selftests/net/forwarding/config
+@@ -6,14 +6,42 @@ CONFIG_IPV6_MULTIPLE_TABLES=y
+ CONFIG_NET_VRF=m
+ CONFIG_BPF_SYSCALL=y
+ CONFIG_CGROUP_BPF=y
++CONFIG_DUMMY=m
++CONFIG_IPV6=y
++CONFIG_IPV6_GRE=m
++CONFIG_MACVLAN=m
+ CONFIG_NET_ACT_CT=m
+ CONFIG_NET_ACT_MIRRED=m
+ CONFIG_NET_ACT_MPLS=m
++CONFIG_NET_ACT_PEDIT=m
++CONFIG_NET_ACT_POLICE=m
++CONFIG_NET_ACT_SAMPLE=m
++CONFIG_NET_ACT_SKBEDIT=m
++CONFIG_NET_ACT_TUNNEL_KEY=m
+ CONFIG_NET_ACT_VLAN=m
+ CONFIG_NET_CLS_FLOWER=m
+ CONFIG_NET_CLS_MATCHALL=m
++CONFIG_NET_CLS_BASIC=m
++CONFIG_NET_EMATCH=y
++CONFIG_NET_EMATCH_META=m
++CONFIG_NET_IPGRE=m
++CONFIG_NET_IPGRE_DEMUX=m
++CONFIG_NET_IPIP=m
++CONFIG_NET_SCH_ETS=m
+ CONFIG_NET_SCH_INGRESS=m
+ CONFIG_NET_ACT_GACT=m
++CONFIG_NET_SCH_PRIO=m
++CONFIG_NET_SCH_RED=m
++CONFIG_NET_SCH_TBF=m
++CONFIG_NET_TC_SKB_EXT=y
++CONFIG_NET_TEAM=y
++CONFIG_NET_TEAM_MODE_LOADBALANCE=y
++CONFIG_NETFILTER=y
++CONFIG_NF_CONNTRACK=m
++CONFIG_NF_FLOW_TABLE=m
++CONFIG_NF_TABLES=m
+ CONFIG_VETH=m
+ CONFIG_NAMESPACES=y
+ CONFIG_NET_NS=y
++CONFIG_VXLAN=m
++CONFIG_XFRM_USER=m
+--
+2.43.0
+
--- /dev/null
+From 50eedaca1a226f60ee8b35f1997def5d3e96fb43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Feb 2024 18:55:38 +0200
+Subject: selftests: forwarding: Add missing multicast routing config entries
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit f0ddf15f0a74c27eb4b2271a90e69948acc3fa2c ]
+
+The two tests that make use of multicast routig (router.sh and
+router_multicast.sh) are currently failing in the netdev CI because the
+kernel is missing multicast routing support.
+
+Fix by adding the required config entries.
+
+Fixes: 6d4efada3b82 ("selftests: forwarding: Add multicast routing test")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20240208165538.1303021-1-idosch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/config | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/tools/testing/selftests/net/forwarding/config b/tools/testing/selftests/net/forwarding/config
+index ba23435145827..8d7a1a004b7c3 100644
+--- a/tools/testing/selftests/net/forwarding/config
++++ b/tools/testing/selftests/net/forwarding/config
+@@ -9,6 +9,13 @@ CONFIG_CGROUP_BPF=y
+ CONFIG_DUMMY=m
+ CONFIG_IPV6=y
+ CONFIG_IPV6_GRE=m
++CONFIG_IPV6_MROUTE=y
++CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
++CONFIG_IPV6_PIMSM_V2=y
++CONFIG_IP_MROUTE=y
++CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
++CONFIG_IP_PIMSM_V1=y
++CONFIG_IP_PIMSM_V2=y
+ CONFIG_MACVLAN=m
+ CONFIG_NET_ACT_CT=m
+ CONFIG_NET_ACT_MIRRED=m
+--
+2.43.0
+
asoc-wm8962-enable-oscillator-if-selecting-wm8962_fl.patch
asoc-wm8962-enable-both-spkoutr_ena-and-spkoutl_ena-.patch
asoc-wm8962-fix-up-incorrect-error-message-in-wm8962.patch
+do_sys_name_to_handle-use-kzalloc-to-fix-kernel-info.patch
+fs-fix-rw_hint-validation.patch
+s390-dasd-add-autoquiesce-feature.patch
+s390-dasd-use-dev_-for-device-log-messages.patch
+s390-dasd-fix-double-module-refcount-decrement.patch
+rcu-exp-fix-rcu-expedited-parallel-grace-period-kwor.patch
+rcu-exp-handle-rcu-expedited-grace-period-kworker-al.patch
+nbd-null-check-for-nla_nest_start.patch
+fs-select-rework-stack-allocation-hack-for-clang.patch
+md-don-t-clear-md_closing-when-the-raid-is-about-to-.patch
+lib-cmdline-fix-an-invalid-format-specifier-in-an-as.patch
+lib-memcpy_kunit-fix-an-invalid-format-specifier-in-.patch
+time-test-fix-incorrect-format-specifier.patch
+rtc-test-fix-invalid-format-specifier.patch
+io_uring-net-unify-how-recvmsg-and-sendmsg-copy-in-t.patch
+io_uring-net-move-receive-multishot-out-of-the-gener.patch
+io_uring-net-fix-overflow-check-in-io_recvmsg_mshot_.patch
+aoe-fix-the-potential-use-after-free-problem-in-aoec.patch
+x86-resctrl-implement-new-mba_mbps-throttling-heuris.patch
+x86-sme-fix-memory-encryption-setting-if-enabled-by-.patch
+timekeeping-fix-cross-timestamp-interpolation-on-cou.patch
+timekeeping-fix-cross-timestamp-interpolation-corner.patch
+timekeeping-fix-cross-timestamp-interpolation-for-no.patch
+sched-fair-take-the-scheduling-domain-into-account-i.patch
+sched-fair-take-the-scheduling-domain-into-account-i.patch-15324
+wifi-ath10k-fix-null-pointer-dereference-in-ath10k_w.patch
+wifi-b43-stop-wake-correct-queue-in-dma-tx-path-when.patch
+wifi-b43-stop-wake-correct-queue-in-pio-tx-path-when.patch
+wifi-b43-stop-correct-queue-in-dma-worker-when-qos-i.patch
+wifi-b43-disable-qos-for-bcm4331.patch
+wifi-wilc1000-fix-declarations-ordering.patch
+wifi-wilc1000-fix-rcu-usage-in-connect-path.patch
+wifi-rtl8xxxu-add-cancel_work_sync-for-c2hcmd_work.patch
+wifi-wilc1000-do-not-realloc-workqueue-everytime-an-.patch
+wifi-wilc1000-fix-multi-vif-management-when-deleting.patch
+wifi-mwifiex-debugfs-drop-unnecessary-error-check-fo.patch
+arm-dts-renesas-r8a73a4-fix-external-clocks-and-cloc.patch
+cpufreq-brcmstb-avs-cpufreq-add-check-for-cpufreq_cp.patch
+cpufreq-explicitly-include-correct-dt-includes.patch
+cpufreq-mediatek-hw-wait-for-cpu-supplies-before-pro.patch
+sock_diag-annotate-data-races-around-sock_diag_handl.patch
+inet_diag-annotate-data-races-around-inet_diag_table.patch
+bpftool-silence-build-warning-about-calloc.patch
+libbpf-apply-map_set_def_max_entries-for-inner_maps-.patch
+selftest-bpf-add-map_in_maps-with-bpf_map_type_perf_.patch
+af_unix-annotate-data-race-of-gc_in_progress-in-wait.patch
+cpufreq-mediatek-hw-don-t-error-out-if-supply-is-not.patch
+libbpf-fix-faccessat-usage-on-android.patch
+pmdomain-qcom-rpmhpd-drop-sa8540p-gfx.lvl.patch
+arm64-dts-imx8mm-kontron-disable-pullups-for-i2c-sig.patch
+arm64-dts-imx8mm-kontron-disable-pullups-for-i2c-sig.patch-29339
+arm64-dts-imx8mm-kontron-disable-pullups-for-onboard.patch
+arm64-dts-imx8mm-kontron-disable-pullups-for-onboard.patch-4465
+arm64-dts-imx8mm-kontron-disable-pull-resistors-for-.patch
+arm64-dts-imx8mm-kontron-disable-pull-resistors-for-.patch-24018
+arm64-dts-imx8mm-kontron-fix-interrupt-for-rtc-on-os.patch
+libbpf-add-missing-libbpf_api-annotation-to-libbpf_s.patch
+wifi-ath9k-delay-all-of-ath9k_wmi_event_tasklet-unti.patch
+wifi-iwlwifi-mvm-report-beacon-protection-failures.patch
+wifi-iwlwifi-dbg-tlv-ensure-nul-termination.patch
+wifi-iwlwifi-fix-ewrd-table-validity-check.patch
+gpio-vf610-allow-disabling-the-vf610-driver.patch
+arm64-dts-imx8mm-venice-gw71xx-fix-usb-otg-vbus.patch
+pwm-atmel-hlcdc-convert-to-platform-remove-callback-.patch
+pwm-atmel-hlcdc-use-consistent-variable-naming.patch
+pwm-atmel-hlcdc-fix-clock-imbalance-related-to-suspe.patch
+net-blackhole_dev-fix-build-warning-for-ethh-set-but.patch
+wifi-ath11k-initialize-rx_mcs_80-and-rx_mcs_160-befo.patch
+wifi-libertas-fix-some-memleaks-in-lbs_allocate_cmd_.patch
+wifi-wfx-fix-memory-leak-when-starting-ap.patch
+arm64-dts-qcom-msm8998-switch-usb-qmp-phy-to-new-sty.patch
+arm64-dts-qcom-msm8998-declare-vls-clamp-register-fo.patch
+arm64-dts-qcom-msm8996-fix-ufs-phy-clocks.patch
+arm64-dts-qcom-msm8998-fix-ufs-phy-clocks.patch
+arm64-dts-qcom-sdm845-switch-ufs-qmp-phy-to-new-styl.patch
+arm64-dts-qcom-sdm845-fix-ufs-phy-clocks.patch
+arm64-dts-qcom-sm6350-fix-ufs-phy-clocks.patch
+arm64-dts-qcom-sm8150-switch-ufs-qmp-phy-to-new-styl.patch
+arm64-dts-qcom-sm8150-fix-ufs-phy-clocks.patch
+arm64-dts-qcom-sm8250-switch-ufs-qmp-phy-to-new-styl.patch
+arm64-dts-qcom-sm8250-fix-ufs-phy-clocks.patch
+arm64-dts-qcom-sc8280xp-update-ufs-phy-nodes.patch
+arm64-dts-qcom-sc8280xp-fix-ufs-phy-clocks.patch
+printk-disable-passing-console-lock-owner-completely.patch
+pwm-sti-fix-capture-for-st-pwm-num-chan-st-capture-n.patch
+tools-resolve_btfids-refactor-set-sorting-with-types.patch
+tools-resolve_btfids-fix-cross-compilation-to-non-ho.patch
+wifi-iwlwifi-mvm-don-t-set-replay-counters-to-0xff.patch
+s390-pai-fix-attr_event_free-upper-limit-for-pai-dev.patch
+s390-vdso-drop-fpic-from-ldflags.patch
+selftests-forwarding-add-missing-config-entries.patch
+selftests-forwarding-add-missing-multicast-routing-c.patch
+ipv6-mcast-remove-one-synchronize_net-barrier-in-ipv.patch
+arm64-dts-mt8183-kukui-split-out-keyboard-node-and-d.patch
+arm64-dts-mt8183-move-crosec-base-detection-node-to-.patch
+arm64-dts-mediatek-mt7986-add-reset-cells-to-infracf.patch
+arm64-dts-mediatek-mt8192-asurada-remove-crosec-base.patch
+arm64-dts-mediatek-mt8192-fix-vencoder-clock-name.patch
+arm64-dts-mediatek-mt7622-add-missing-device_type-to.patch
+bpf-mark-bpf_spin_-lock-unlock-helpers-with-notrace-.patch
+selftests-bpf-convert-test_global_funcs-test-to-test.patch
+selftests-bpf-add-global-subprog-context-passing-tes.patch
+bpf-don-t-infer-ptr_to_ctx-for-programs-with-unnamed.patch
+arm64-dts-qcom-msm8996-define-ufs-unipro-clock-limit.patch
+arm-dts-qcom-msm8974-correct-qfprom-node-size.patch
+wifi-wilc1000-prevent-use-after-free-on-vif-when-cle.patch
+acpi-processor_idle-fix-memory-leak-in-acpi_processo.patch
+bus-tegra-aconnect-update-dependency-to-arch_tegra.patch
+iommu-amd-mark-interrupt-as-managed.patch
+wifi-brcmsmac-avoid-function-pointer-casts.patch
+arm64-dts-qcom-sdm845-db845c-correct-pcie-wake-gpios.patch
+arm64-dts-qcom-sm8150-use-gpios-suffix-for-pci-gpios.patch
+arm64-dts-qcom-sm8150-correct-pcie-wake-gpios.patch
+powercap-dtpm_cpu-fix-error-check-against-freq_qos_a.patch
+net-ena-remove-ena_select_queue.patch
+arm64-dts-mt8195-cherry-tomato-change-watchdog-reset.patch
+firmware-arm_scmi-fix-double-free-in-smc-transport-c.patch
+wifi-wilc1000-revert-reset-line-logic-flip.patch
+arm-dts-arm-realview-fix-development-chip-rom-compat.patch
+arm64-dts-renesas-r9a07g043-split-out-rz-g2ul-soc-sp.patch
+arm64-dts-renesas-r9a07g043u-add-irqc-node.patch
+arm64-dts-renesas-rzg2l-add-missing-interrupts-to-ir.patch
+arm64-dts-renesas-r8a779a0-update-to-r-car-gen4-comp.patch
+arm64-dts-renesas-r8a779a0-correct-avb-01-reg-sizes.patch
+arm64-dts-renesas-r8a779g0-correct-avb-01-reg-sizes.patch
+net-mctp-copy-skb-ext-data-when-fragmenting.patch
+pstore-inode-convert-mutex-usage-to-guard-mutex.patch
+pstore-inode-only-d_invalidate-is-needed.patch
+arm64-dts-allwinner-h6-add-rx-dma-channel-for-spdif.patch
+arm-dts-imx6dl-yapp4-move-phy-reset-into-switch-node.patch
+arm-dts-imx6dl-yapp4-fix-typo-in-the-qca-switch-regi.patch
+arm-dts-imx6dl-yapp4-move-the-internal-switch-phys-u.patch
+arm64-dts-marvell-reorder-crypto-interrupts-on-armad.patch
+acpi-resource-add-infinity-laptops-to-irq1_edge_low_.patch
+acpi-resource-do-irq-override-on-lunnen-ground-lapto.patch
+acpi-resource-add-maibenben-x577-to-irq1_edge_low_fo.patch
+acpi-scan-fix-device-check-notification-handling.patch
+arm64-dts-rockchip-add-missing-interrupt-names-for-r.patch
+x86-relocs-ignore-relocations-in-.notes-section.patch
+sunrpc-fix-some-memleaks-in-gssx_dec_option_array.patch
+mmc-wmt-sdmmc-remove-an-incorrect-release_mem_region.patch
+acpi-cppc-enable-amd-cppc-v2-support-for-family-17h-.patch
+wifi-rtw88-8821c-fix-beacon-loss-and-disconnect.patch
+wifi-rtw88-8821c-fix-false-alarm-count.patch
+pci-make-pci_dev_is_disconnected-helper-public-for-o.patch
+iommu-vt-d-don-t-issue-ats-invalidation-request-when.patch
+igb-fix-missing-time-sync-events.patch
+bluetooth-remove-hci_power_off_timeout.patch
+bluetooth-mgmt-remove-leftover-queuing-of-power_off-.patch
+bluetooth-remove-superfluous-call-to-hci_conn_check_.patch
+bluetooth-hci_qca-don-t-use-is_err_or_null-with-gpio.patch
+bluetooth-cancel-sync-command-before-suspend-and-pow.patch
+bluetooth-hci_sync-only-allow-hci_cmd_sync_queue-if-.patch
+bluetooth-hci_conn-consolidate-code-for-aborting-con.patch
+bluetooth-hci_core-cancel-request-on-command-timeout.patch
+bluetooth-hci_sync-fix-overwriting-request-callback.patch
+bluetooth-hci_core-fix-possible-buffer-overflow.patch
+bluetooth-af_bluetooth-fix-deadlock.patch
+bluetooth-fix-use-after-free-in-accessing-skb-after-.patch
+sr9800-add-check-for-usbnet_get_endpoints.patch
+s390-cache-prevent-rebuild-of-shared_cpu_list.patch
+bpf-fix-devmap_hash-overflow-check-on-32-bit-arches.patch
+bpf-fix-hashtab-overflow-check-on-32-bit-arches.patch
+bpf-fix-stackmap-overflow-check-on-32-bit-arches.patch
+iommu-vt-d-retrieve-iommu-perfmon-capability-informa.patch
+iommu-fix-compilation-without-config_iommu_intel.patch
+ipv6-fib6_rules-flush-route-cache-when-rule-is-chang.patch
+net-ip_tunnel-make-sure-to-pull-inner-header-in-ip_t.patch
+net-phy-fix-phy_get_internal_delay-accessing-an-empt.patch
+net-hns3-fix-wrong-judgment-condition-issue.patch
+net-hns3-fix-kernel-crash-when-1588-is-received-on-h.patch
+net-hns3-fix-port-duplex-configure-error-in-imp-rese.patch
+bluetooth-mgmt-fix-always-using-hci_max_ad_length.patch
+bluetooth-hci_core-fix-missing-instances-using-hci_m.patch
+bluetooth-fix-eir-name-length.patch
+net-phy-dp83822-fix-rgmii-tx-delay-configuration.patch
+opp-debugfs-fix-warning-around-icc_get_name.patch
+tcp-fix-incorrect-parameter-validation-in-the-do_tcp.patch
+ipmr-fix-incorrect-parameter-validation-in-the-ip_mr.patch
+l2tp-fix-incorrect-parameter-validation-in-the-pppol.patch
+udp-fix-incorrect-parameter-validation-in-the-udp_li.patch
+net-kcm-fix-incorrect-parameter-validation-in-the-kc.patch
+net-x25-fix-incorrect-parameter-validation-in-the-x2.patch
+nfp-flower-handle-acti_netdevs-allocation-failure.patch
+bpf-hardcode-bpf_prog_pack_size-to-2mb-num_possible_.patch
+dm-raid-fix-false-positive-for-requeue-needed-during.patch
+dm-call-the-resume-method-on-internal-suspend.patch
+drm-tegra-dsi-add-missing-check-for-of_find_device_b.patch
+drm-tegra-dpaux-fix-pm-disable-depth-imbalance-in-te.patch
+drm-tegra-dsi-make-use-of-the-helper-function-dev_er.patch
+drm-tegra-dsi-fix-some-error-handling-paths-in-tegra.patch
+drm-tegra-dsi-fix-missing-pm_runtime_disable-in-the-.patch
+drm-tegra-hdmi-convert-to-devm_platform_ioremap_reso.patch
+drm-tegra-hdmi-fix-some-error-handling-paths-in-tegr.patch
+drm-tegra-rgb-fix-some-error-handling-paths-in-tegra.patch
+drm-tegra-rgb-fix-missing-clk_put-in-the-error-handl.patch
+drm-tegra-output-fix-missing-i2c_put_adapter-in-the-.patch
+drm-rockchip-inno_hdmi-fix-video-timing.patch
+drm-don-t-treat-0-as-1-in-drm_fixp2int_ceil.patch
+drm-vmwgfx-fix-a-memleak-in-vmw_gmrid_man_get_node.patch
+drm-rockchip-lvds-do-not-overwrite-error-code.patch
+drm-rockchip-lvds-do-not-print-scary-message-when-pr.patch
+drm-panel-edp-use-put_sync-in-unprepare.patch
+drm-lima-fix-a-memleak-in-lima_heap_alloc.patch
+asoc-amd-acp-add-missing-error-handling-in-sof-mach.patch
+dmaengine-tegra210-adma-update-dependency-to-arch_te.patch
+media-tc358743-register-v4l2-async-device-only-after.patch
+pci-dpc-print-all-tlp-prefixes-not-just-the-first.patch
+perf-record-fix-possible-incorrect-free-in-record__s.patch
+hid-lenovo-add-middleclick_workaround-sysfs-knob-for.patch
+drm-amd-display-fix-a-potential-buffer-overflow-in-d.patch
+drm-amd-display-fix-potential-null-pointer-dereferen.patch
+pinctrl-renesas-r8a779g0-add-audio-ssi-pins-groups-a.patch
+pinctrl-renesas-r8a779g0-add-missing-scif_clk2-pin-g.patch
+clk-samsung-exynos850-propagate-spi-ipclk-rate-chang.patch
+perf-evsel-fix-duplicate-initialization-of-data-id-i.patch
+pci-aer-fix-rootport-attribute-paths-in-abi-docs.patch
+clk-meson-add-missing-clocks-to-axg_clk_regmaps.patch
+media-em28xx-annotate-unchecked-call-to-media_device.patch
+media-v4l2-tpg-fix-some-memleaks-in-tpg_alloc.patch
+media-v4l2-mem2mem-fix-a-memleak-in-v4l2_m2m_registe.patch
+media-edia-dvbdev-fix-a-use-after-free.patch
+pinctrl-mediatek-drop-bogus-slew-rate-register-range.patch
+pinctrl-mediatek-drop-bogus-slew-rate-register-range.patch-28108
+clk-qcom-reset-commonize-the-de-assert-functions.patch
+clk-qcom-reset-ensure-write-completion-on-reset-de-a.patch
+dt-bindings-clock-qcom-add-missing-ufs-qref-clocks.patch
+clk-qcom-gcc-sc8180x-add-missing-ufs-qref-clocks.patch
+quota-simplify-drop_dquot_ref.patch
+quota-fix-potential-null-pointer-dereference.patch
+quota-fix-rcu-annotations-of-inode-dquot-pointers.patch
+pci-switchtec-fix-an-error-handling-path-in-switchte.patch
+crypto-xilinx-call-finalize-with-bh-disabled.patch
+perf-thread_map-free-strlist-on-normal-path-in-threa.patch
+drm-msm-dpu-fix-the-programming-of-intf_cfg2_data_hc.patch
+drm-msm-dpu-only-enable-dsc_mode_multiplex-if-dsc_me.patch
+drm-radeon-ni-fix-wrong-firmware-size-logging-in-ni_.patch
+clk-renesas-r8a779g0-add-cmt-clocks.patch
+clk-renesas-r8a779g0-add-audio-clocks.patch
+clk-renesas-r8a779g0-add-thermal-clock.patch
+clk-renesas-r8a779g0-correct-pfc-gpio-parent-clocks.patch
+clk-renesas-r8a779f0-correct-pfc-gpio-parent-clock.patch
+alsa-seq-fix-function-cast-warnings.patch
+perf-stat-avoid-metric-only-segv.patch
+asoc-meson-aiu-fix-function-pointer-type-mismatch.patch
+asoc-meson-t9015-fix-function-pointer-type-mismatch.patch
+powerpc-force-inlining-of-arch_vmap_p-u-m-d_supporte.patch
+asoc-sof-introduce-container-struct-for-sof-firmware.patch
+asoc-sof-add-some-bounds-checking-to-firmware-data.patch
+ntb-epf-fix-possible-memory-leak-in-pci_vntb_probe.patch
+ntb-fix-possible-name-leak-in-ntb_register_device.patch
+media-cedrus-h265-associate-mv-col-buffers-with-buff.patch
+media-cedrus-h265-fix-configuring-bitstream-size.patch
+media-sun8i-di-fix-coefficient-writes.patch
+media-sun8i-di-fix-power-on-off-sequences.patch
+media-sun8i-di-fix-chroma-difference-threshold.patch
+media-imx-csc-scaler-fix-v4l2_ctrl_handler-memory-le.patch
+media-go7007-add-check-of-return-value-of-go7007_rea.patch
+media-pvrusb2-remove-redundant-null-check.patch
+media-pvrusb2-fix-pvr2_stream_callback-casts.patch
+clk-qcom-dispcc-sdm845-adjust-internal-gdsc-wait-tim.patch
+drm-mediatek-dsi-fix-dsi-rgb666-formats-and-definiti.patch
+pci-mark-3ware-9650se-root-port-extended-tags-as-bro.patch
+clk-hisilicon-hi3519-release-the-correct-number-of-g.patch
+clk-hisilicon-hi3559a-fix-an-erroneous-devm_kfree.patch
+drm-tegra-put-drm_gem_object-ref-on-error-in-tegra_f.patch
+mfd-syscon-call-of_node_put-only-when-of_parse_phand.patch
+mfd-altera-sysmgr-call-of_node_put-only-when-of_pars.patch
+crypto-arm-sha-fix-function-cast-warnings.patch
+crypto-jitter-fix-crypto_jitterentropy-help-text.patch
+drm-tidss-fix-initial-plane-zpos-values.patch
+drm-tidss-fix-sync-lost-issue-with-two-displays.patch
+mtd-maps-physmap-core-fix-flash-size-larger-than-32-.patch
+mtd-rawnand-lpc32xx_mlc-fix-irq-handler-prototype.patch
+asoc-meson-axg-tdm-interface-fix-mclk-setup-without-.patch
+asoc-meson-axg-tdm-interface-add-frame-rate-constrai.patch
+hid-amd_sfh-update-hpd-sensor-structure-elements.patch
+hid-amd_sfh-avoid-disabling-the-interrupt.patch
+drm-amdgpu-fix-missing-break-in-atom_arg_imm-case-of.patch
+media-pvrusb2-fix-uaf-in-pvr2_context_set_notify.patch
+media-dvb-frontends-avoid-stack-overflow-warnings-wi.patch
+media-go7007-fix-a-memleak-in-go7007_load_encoder.patch
+media-ttpci-fix-two-memleaks-in-budget_av_attach.patch
+media-mediatek-vcodec-avoid-wcast-function-type-stri.patch
+gpio-nomadik-fix-offset-bug-in-nmk_pmx_set.patch
+drm-mediatek-fix-a-null-pointer-crash-in-mtk_drm_crt.patch
+powerpc-pseries-fix-potential-memleak-in-papr_get_at.patch
+powerpc-hv-gpci-fix-the-h_get_perf_counter_info-hcal.patch
+drm-msm-dpu-add-division-of-drm_display_mode-s-hskew.patch
+modules-wait-do_free_init-correctly.patch
+powerpc-embedded6xx-fix-no-previous-prototype-for-av.patch
+leds-aw2013-unlock-mutex-before-destroying-it.patch
+leds-sgm3140-add-missing-timer-cleanup-and-flash-gpi.patch
+backlight-lm3630a-initialize-backlight_properties-on.patch
+backlight-lm3630a-don-t-set-bl-props.brightness-in-g.patch
+backlight-da9052-fully-initialize-backlight_properti.patch
+backlight-lm3639-fully-initialize-backlight_properti.patch
+backlight-lp8788-fully-initialize-backlight_properti.patch
+arch-powerpc-remove-linux-fb.h-from-backlight-code.patch
+sparc32-fix-section-mismatch-in-leon_pci_grpci.patch
+clk-fix-clk_core_get-null-dereference.patch
+clk-zynq-prevent-null-pointer-dereference-caused-by-.patch
+alsa-hda-realtek-fix-alc285-issues-on-hp-envy-x360-l.patch
+alsa-usb-audio-stop-parsing-channels-bits-when-all-c.patch
+rdma-irdma-allow-accurate-reporting-on-qp-max-send-r.patch
+rdma-irdma-remove-duplicate-assignment.patch
+rdma-srpt-do-not-register-event-handler-until-srpt-d.patch
+f2fs-reduce-stack-memory-cost-by-using-bitfield-in-s.patch
+f2fs-compress-fix-to-guarantee-persisting-compressed.patch
+f2fs-compress-fix-to-cover-normal-cluster-write-with.patch
+f2fs-compress-fix-to-check-unreleased-compressed-clu.patch
+f2fs-simplify-__allocate_data_block.patch
+f2fs-delete-obsolete-fi_first_block_written.patch
+f2fs-delete-obsolete-fi_drop_cache.patch
+f2fs-introduce-get_dnode_addr-to-clean-up-codes.patch
+f2fs-update-blkaddr-in-__set_data_blkaddr-for-cleanu.patch
+f2fs-compress-fix-to-avoid-inconsistence-bewteen-i_b.patch
+f2fs-compress-fix-to-cover-f2fs_disable_compressed_f.patch
+f2fs-fix-to-avoid-potential-panic-during-recovery.patch
+scsi-csiostor-avoid-function-pointer-casts.patch
+rdma-hns-fix-mis-modifying-default-congestion-contro.patch
+rdma-device-fix-a-race-between-mad_client-and-cm_cli.patch
+rdma-rtrs-clt-check-strnlen-return-len-in-sysfs-mpat.patch
+scsi-bfa-fix-function-pointer-type-mismatch-for-hcb_.patch
+f2fs-compress-fix-to-check-zstd-compress-level-corre.patch
+net-sunrpc-fix-an-off-by-one-in-rpc_sockaddr2uaddr.patch
+nfsv4.2-fix-nfs4_listxattr-kernel-bug-at-mm-usercopy.patch
+nfsv4.2-fix-listxattr-maximum-xdr-buffer-size.patch
+f2fs-compress-fix-to-check-compress-flag-w-.i_sem-lo.patch
+f2fs-check-number-of-blocks-in-a-current-section.patch
+watchdog-stm32_iwdg-initialize-default-timeout.patch
+f2fs-ro-compress-fix-to-avoid-caching-unaligned-exte.patch
+nfs-fix-an-off-by-one-in-root_nfs_cat.patch
+f2fs-convert-to-use-sbi-directly.patch
+f2fs-compress-relocate-some-judgments-in-f2fs_reserv.patch
+f2fs-compress-fix-reserve_cblocks-counting-error-whe.patch
+perf-x86-amd-core-avoid-register-reset-when-cpu-is-d.patch
+afs-revert-afs-hide-silly-rename-files-from-userspac.patch
+nfs-fix-panic-when-nfs4_ff_layout_prepare_ds-fails.patch
+io_uring-net-correct-the-type-of-variable.patch
--- /dev/null
+From 902b1287101a653fd4e31b2a5b5391ff93bdba35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jan 2024 11:25:55 +0000
+Subject: sock_diag: annotate data-races around sock_diag_handlers[family]
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit efd402537673f9951992aea4ef0f5ff51d858f4b ]
+
+__sock_diag_cmd() and sock_diag_bind() read sock_diag_handlers[family]
+without a lock held.
+
+Use READ_ONCE()/WRITE_ONCE() annotations to avoid potential issues.
+
+Fixes: 8ef874bfc729 ("sock_diag: Move the sock_ code to net/core/")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Guillaume Nault <gnault@redhat.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock_diag.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c
+index f7cf74cdd3db1..e6ea6764d10ab 100644
+--- a/net/core/sock_diag.c
++++ b/net/core/sock_diag.c
+@@ -190,7 +190,7 @@ int sock_diag_register(const struct sock_diag_handler *hndl)
+ if (sock_diag_handlers[hndl->family])
+ err = -EBUSY;
+ else
+- sock_diag_handlers[hndl->family] = hndl;
++ WRITE_ONCE(sock_diag_handlers[hndl->family], hndl);
+ mutex_unlock(&sock_diag_table_mutex);
+
+ return err;
+@@ -206,7 +206,7 @@ void sock_diag_unregister(const struct sock_diag_handler *hnld)
+
+ mutex_lock(&sock_diag_table_mutex);
+ BUG_ON(sock_diag_handlers[family] != hnld);
+- sock_diag_handlers[family] = NULL;
++ WRITE_ONCE(sock_diag_handlers[family], NULL);
+ mutex_unlock(&sock_diag_table_mutex);
+ }
+ EXPORT_SYMBOL_GPL(sock_diag_unregister);
+@@ -224,7 +224,7 @@ static int __sock_diag_cmd(struct sk_buff *skb, struct nlmsghdr *nlh)
+ return -EINVAL;
+ req->sdiag_family = array_index_nospec(req->sdiag_family, AF_MAX);
+
+- if (sock_diag_handlers[req->sdiag_family] == NULL)
++ if (READ_ONCE(sock_diag_handlers[req->sdiag_family]) == NULL)
+ sock_load_diag_module(req->sdiag_family, 0);
+
+ mutex_lock(&sock_diag_table_mutex);
+@@ -283,12 +283,12 @@ static int sock_diag_bind(struct net *net, int group)
+ switch (group) {
+ case SKNLGRP_INET_TCP_DESTROY:
+ case SKNLGRP_INET_UDP_DESTROY:
+- if (!sock_diag_handlers[AF_INET])
++ if (!READ_ONCE(sock_diag_handlers[AF_INET]))
+ sock_load_diag_module(AF_INET, 0);
+ break;
+ case SKNLGRP_INET6_TCP_DESTROY:
+ case SKNLGRP_INET6_UDP_DESTROY:
+- if (!sock_diag_handlers[AF_INET6])
++ if (!READ_ONCE(sock_diag_handlers[AF_INET6]))
+ sock_load_diag_module(AF_INET6, 0);
+ break;
+ }
+--
+2.43.0
+
--- /dev/null
+From 77ff2876294ed7e18f7ef7059f9ee81d14356b23 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 Feb 2024 18:42:28 +0100
+Subject: sparc32: Fix section mismatch in leon_pci_grpci
+
+From: Sam Ravnborg <sam@ravnborg.org>
+
+[ Upstream commit 24338a6ae13cb743ced77da1b3a12c83f08a0c96 ]
+
+Passing a datastructre marked _initconst to platform_driver_register()
+is wrong. Drop the __initconst notation.
+
+This fixes the following warnings:
+
+WARNING: modpost: vmlinux: section mismatch in reference: grpci1_of_driver+0x30 (section: .data) -> grpci1_of_match (section: .init.rodata)
+WARNING: modpost: vmlinux: section mismatch in reference: grpci2_of_driver+0x30 (section: .data) -> grpci2_of_match (section: .init.rodata)
+
+Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Andreas Larsson <andreas@gaisler.com>
+Fixes: 4154bb821f0b ("sparc: leon: grpci1: constify of_device_id")
+Fixes: 03949b1cb9f1 ("sparc: leon: grpci2: constify of_device_id")
+Tested-by: Randy Dunlap <rdunlap@infradead.org> # build-tested
+Reviewed-by: Andreas Larsson <andreas@gaisler.com>
+Tested-by: Andreas Larsson <andreas@gaisler.com>
+Signed-off-by: Andreas Larsson <andreas@gaisler.com>
+Link: https://lore.kernel.org/r/20240224-sam-fix-sparc32-all-builds-v2-7-1f186603c5c4@ravnborg.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/sparc/kernel/leon_pci_grpci1.c | 2 +-
+ arch/sparc/kernel/leon_pci_grpci2.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/sparc/kernel/leon_pci_grpci1.c b/arch/sparc/kernel/leon_pci_grpci1.c
+index e6935d0ac1ec9..c32590bdd3120 100644
+--- a/arch/sparc/kernel/leon_pci_grpci1.c
++++ b/arch/sparc/kernel/leon_pci_grpci1.c
+@@ -696,7 +696,7 @@ static int grpci1_of_probe(struct platform_device *ofdev)
+ return err;
+ }
+
+-static const struct of_device_id grpci1_of_match[] __initconst = {
++static const struct of_device_id grpci1_of_match[] = {
+ {
+ .name = "GAISLER_PCIFBRG",
+ },
+diff --git a/arch/sparc/kernel/leon_pci_grpci2.c b/arch/sparc/kernel/leon_pci_grpci2.c
+index ca22f93d90454..dd06abc61657f 100644
+--- a/arch/sparc/kernel/leon_pci_grpci2.c
++++ b/arch/sparc/kernel/leon_pci_grpci2.c
+@@ -887,7 +887,7 @@ static int grpci2_of_probe(struct platform_device *ofdev)
+ return err;
+ }
+
+-static const struct of_device_id grpci2_of_match[] __initconst = {
++static const struct of_device_id grpci2_of_match[] = {
+ {
+ .name = "GAISLER_GRPCI2",
+ },
+--
+2.43.0
+
--- /dev/null
+From 39eb1924582299d551b81f5d40db47c8c24955d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 07:59:27 +0000
+Subject: sr9800: Add check for usbnet_get_endpoints
+
+From: Chen Ni <nichen@iscas.ac.cn>
+
+[ Upstream commit 07161b2416f740a2cb87faa5566873f401440a61 ]
+
+Add check for usbnet_get_endpoints() and return the error if it fails
+in order to transfer the error.
+
+Signed-off-by: Chen Ni <nichen@iscas.ac.cn>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Fixes: 19a38d8e0aa3 ("USB2NET : SR9800 : One chip USB2.0 USB2NET SR9800 Device Driver Support")
+Link: https://lore.kernel.org/r/20240305075927.261284-1-nichen@iscas.ac.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/sr9800.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/sr9800.c b/drivers/net/usb/sr9800.c
+index f5e19f3ef6cdd..4de5144821835 100644
+--- a/drivers/net/usb/sr9800.c
++++ b/drivers/net/usb/sr9800.c
+@@ -737,7 +737,9 @@ static int sr9800_bind(struct usbnet *dev, struct usb_interface *intf)
+
+ data->eeprom_len = SR9800_EEPROM_LEN;
+
+- usbnet_get_endpoints(dev, intf);
++ ret = usbnet_get_endpoints(dev, intf);
++ if (ret)
++ goto out;
+
+ /* LED Setting Rule :
+ * AABB:CCDD
+--
+2.43.0
+
--- /dev/null
+From 684f20e41b9770fecce64f41a0031e49e4d374e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jan 2024 13:38:13 +0800
+Subject: SUNRPC: fix some memleaks in gssx_dec_option_array
+
+From: Zhipeng Lu <alexious@zju.edu.cn>
+
+[ Upstream commit 3cfcfc102a5e57b021b786a755a38935e357797d ]
+
+The creds and oa->data need to be freed in the error-handling paths after
+their allocation. So this patch add these deallocations in the
+corresponding paths.
+
+Fixes: 1d658336b05f ("SUNRPC: Add RPC based upcall mechanism for RPCGSS auth")
+Signed-off-by: Zhipeng Lu <alexious@zju.edu.cn>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sunrpc/auth_gss/gss_rpc_xdr.c | 27 +++++++++++++++++++--------
+ 1 file changed, 19 insertions(+), 8 deletions(-)
+
+diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c
+index d79f12c2550ac..cb32ab9a83952 100644
+--- a/net/sunrpc/auth_gss/gss_rpc_xdr.c
++++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c
+@@ -250,8 +250,8 @@ static int gssx_dec_option_array(struct xdr_stream *xdr,
+
+ creds = kzalloc(sizeof(struct svc_cred), GFP_KERNEL);
+ if (!creds) {
+- kfree(oa->data);
+- return -ENOMEM;
++ err = -ENOMEM;
++ goto free_oa;
+ }
+
+ oa->data[0].option.data = CREDS_VALUE;
+@@ -265,29 +265,40 @@ static int gssx_dec_option_array(struct xdr_stream *xdr,
+
+ /* option buffer */
+ p = xdr_inline_decode(xdr, 4);
+- if (unlikely(p == NULL))
+- return -ENOSPC;
++ if (unlikely(p == NULL)) {
++ err = -ENOSPC;
++ goto free_creds;
++ }
+
+ length = be32_to_cpup(p);
+ p = xdr_inline_decode(xdr, length);
+- if (unlikely(p == NULL))
+- return -ENOSPC;
++ if (unlikely(p == NULL)) {
++ err = -ENOSPC;
++ goto free_creds;
++ }
+
+ if (length == sizeof(CREDS_VALUE) &&
+ memcmp(p, CREDS_VALUE, sizeof(CREDS_VALUE)) == 0) {
+ /* We have creds here. parse them */
+ err = gssx_dec_linux_creds(xdr, creds);
+ if (err)
+- return err;
++ goto free_creds;
+ oa->data[0].value.len = 1; /* presence */
+ } else {
+ /* consume uninteresting buffer */
+ err = gssx_dec_buffer(xdr, &dummy);
+ if (err)
+- return err;
++ goto free_creds;
+ }
+ }
+ return 0;
++
++free_creds:
++ kfree(creds);
++free_oa:
++ kfree(oa->data);
++ oa->data = NULL;
++ return err;
+ }
+
+ static int gssx_dec_status(struct xdr_stream *xdr,
+--
+2.43.0
+
--- /dev/null
+From b8d28ee354fd93c2a7e11ba9beb89f648dd95952 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 14:23:49 +0000
+Subject: tcp: fix incorrect parameter validation in the do_tcp_getsockopt()
+ function
+
+From: Gavrilov Ilia <Ilia.Gavrilov@infotecs.ru>
+
+[ Upstream commit 716edc9706deb3bb2ff56e2eeb83559cea8f22db ]
+
+The 'len' variable can't be negative when assigned the result of
+'min_t' because all 'min_t' parameters are cast to unsigned int,
+and then the minimum one is chosen.
+
+To fix the logic, check 'len' as read from 'optlen',
+where the types of relevant variables are (signed) int.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Gavrilov Ilia <Ilia.Gavrilov@infotecs.ru>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 86e7695d91adf..5a165e29f7be4 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -4102,11 +4102,11 @@ int do_tcp_getsockopt(struct sock *sk, int level,
+ if (copy_from_sockptr(&len, optlen, sizeof(int)))
+ return -EFAULT;
+
+- len = min_t(unsigned int, len, sizeof(int));
+-
+ if (len < 0)
+ return -EINVAL;
+
++ len = min_t(unsigned int, len, sizeof(int));
++
+ switch (optname) {
+ case TCP_MAXSEG:
+ val = tp->mss_cache;
+--
+2.43.0
+
--- /dev/null
+From a5c296c63083952f05884e35c533f8de8580bee5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Feb 2024 17:27:17 +0800
+Subject: time: test: Fix incorrect format specifier
+
+From: David Gow <davidgow@google.com>
+
+[ Upstream commit 133e267ef4a26d19c93996a874714e9f3f8c70aa ]
+
+'days' is a s64 (from div_s64), and so should use a %lld specifier.
+
+This was found by extending KUnit's assertion macros to use gcc's
+__printf attribute.
+
+Fixes: 276010551664 ("time: Improve performance of time64_to_tm()")
+Signed-off-by: David Gow <davidgow@google.com>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Justin Stitt <justinstitt@google.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/time_test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/time/time_test.c b/kernel/time/time_test.c
+index 831e8e779acef..f7c3de01197c9 100644
+--- a/kernel/time/time_test.c
++++ b/kernel/time/time_test.c
+@@ -73,7 +73,7 @@ static void time64_to_tm_test_date_range(struct kunit *test)
+
+ days = div_s64(secs, 86400);
+
+- #define FAIL_MSG "%05ld/%02d/%02d (%2d) : %ld", \
++ #define FAIL_MSG "%05ld/%02d/%02d (%2d) : %lld", \
+ year, month, mdday, yday, days
+
+ KUNIT_ASSERT_EQ_MSG(test, year - 1900, result.tm_year, FAIL_MSG);
+--
+2.43.0
+
--- /dev/null
+From 82bb7d81e053728feb06395301126e0b4a35ba1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Dec 2023 08:38:40 +0100
+Subject: timekeeping: Fix cross-timestamp interpolation corner case decision
+
+From: Peter Hilber <peter.hilber@opensynergy.com>
+
+[ Upstream commit 87a41130881995f82f7adbafbfeddaebfb35f0ef ]
+
+The cycle_between() helper checks if parameter test is in the open interval
+(before, after). Colloquially speaking, this also applies to the counter
+wrap-around special case before > after. get_device_system_crosststamp()
+currently uses cycle_between() at the first call site to decide whether to
+interpolate for older counter readings.
+
+get_device_system_crosststamp() has the following problem with
+cycle_between() testing against an open interval: Assume that, by chance,
+cycles == tk->tkr_mono.cycle_last (in the following, "cycle_last" for
+brevity). Then, cycle_between() at the first call site, with effective
+argument values cycle_between(cycle_last, cycles, now), returns false,
+enabling interpolation. During interpolation,
+get_device_system_crosststamp() will then call cycle_between() at the
+second call site (if a history_begin was supplied). The effective argument
+values are cycle_between(history_begin->cycles, cycles, cycles), since
+system_counterval.cycles == interval_start == cycles, per the assumption.
+Due to the test against the open interval, cycle_between() returns false
+again. This causes get_device_system_crosststamp() to return -EINVAL.
+
+This failure should be avoided, since get_device_system_crosststamp() works
+both when cycles follows cycle_last (no interpolation), and when cycles
+precedes cycle_last (interpolation). For the case cycles == cycle_last,
+interpolation is actually unneeded.
+
+Fix this by changing cycle_between() into timestamp_in_interval(), which
+now checks against the closed interval, rather than the open interval.
+
+This changes the get_device_system_crosststamp() behavior for three corner
+cases:
+
+1. Bypass interpolation in the case cycles == tk->tkr_mono.cycle_last,
+ fixing the problem described above.
+
+2. At the first timestamp_in_interval() call site, cycles == now no longer
+ causes failure.
+
+3. At the second timestamp_in_interval() call site, history_begin->cycles
+ == system_counterval.cycles no longer causes failure.
+ adjust_historical_crosststamp() also works for this corner case,
+ where partial_history_cycles == total_history_cycles.
+
+These behavioral changes should not cause any problems.
+
+Fixes: 2c756feb18d9 ("time: Add history to cross timestamp interface supporting slower devices")
+Signed-off-by: Peter Hilber <peter.hilber@opensynergy.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/r/20231218073849.35294-3-peter.hilber@opensynergy.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/timekeeping.c | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
+index c168931c78e01..1749a712f72d1 100644
+--- a/kernel/time/timekeeping.c
++++ b/kernel/time/timekeeping.c
+@@ -1180,13 +1180,15 @@ static int adjust_historical_crosststamp(struct system_time_snapshot *history,
+ }
+
+ /*
+- * cycle_between - true if test occurs chronologically between before and after
++ * timestamp_in_interval - true if ts is chronologically in [start, end]
++ *
++ * True if ts occurs chronologically at or after start, and before or at end.
+ */
+-static bool cycle_between(u64 before, u64 test, u64 after)
++static bool timestamp_in_interval(u64 start, u64 end, u64 ts)
+ {
+- if (test > before && test < after)
++ if (ts >= start && ts <= end)
+ return true;
+- if (before > after && (test > before || test < after))
++ if (start > end && (ts >= start || ts <= end))
+ return true;
+ return false;
+ }
+@@ -1246,7 +1248,7 @@ int get_device_system_crosststamp(int (*get_time_fn)
+ */
+ now = tk_clock_read(&tk->tkr_mono);
+ interval_start = tk->tkr_mono.cycle_last;
+- if (!cycle_between(interval_start, cycles, now)) {
++ if (!timestamp_in_interval(interval_start, now, cycles)) {
+ clock_was_set_seq = tk->clock_was_set_seq;
+ cs_was_changed_seq = tk->cs_was_changed_seq;
+ cycles = interval_start;
+@@ -1277,13 +1279,13 @@ int get_device_system_crosststamp(int (*get_time_fn)
+ bool discontinuity;
+
+ /*
+- * Check that the counter value occurs after the provided
++ * Check that the counter value is not before the provided
+ * history reference and that the history doesn't cross a
+ * clocksource change
+ */
+ if (!history_begin ||
+- !cycle_between(history_begin->cycles,
+- system_counterval.cycles, cycles) ||
++ !timestamp_in_interval(history_begin->cycles,
++ cycles, system_counterval.cycles) ||
+ history_begin->cs_was_changed_seq != cs_was_changed_seq)
+ return -EINVAL;
+ partial_history_cycles = cycles - system_counterval.cycles;
+--
+2.43.0
+
--- /dev/null
+From baae7e7e34f12fc96d3e33e61bd66c78c25d0e19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Dec 2023 08:38:41 +0100
+Subject: timekeeping: Fix cross-timestamp interpolation for non-x86
+
+From: Peter Hilber <peter.hilber@opensynergy.com>
+
+[ Upstream commit 14274d0bd31b4debf28284604589f596ad2e99f2 ]
+
+So far, get_device_system_crosststamp() unconditionally passes
+system_counterval.cycles to timekeeping_cycles_to_ns(). But when
+interpolating system time (do_interp == true), system_counterval.cycles is
+before tkr_mono.cycle_last, contrary to the timekeeping_cycles_to_ns()
+expectations.
+
+On x86, CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE will mitigate on
+interpolating, setting delta to 0. With delta == 0, xtstamp->sys_monoraw
+and xtstamp->sys_realtime are then set to the last update time, as
+implicitly expected by adjust_historical_crosststamp(). On other
+architectures, the resulting nonsense xtstamp->sys_monoraw and
+xtstamp->sys_realtime corrupt the xtstamp (ts) adjustment in
+adjust_historical_crosststamp().
+
+Fix this by deriving xtstamp->sys_monoraw and xtstamp->sys_realtime from
+the last update time when interpolating, by using the local variable
+"cycles". The local variable already has the right value when
+interpolating, unlike system_counterval.cycles.
+
+Fixes: 2c756feb18d9 ("time: Add history to cross timestamp interface supporting slower devices")
+Signed-off-by: Peter Hilber <peter.hilber@opensynergy.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: John Stultz <jstultz@google.com>
+Link: https://lore.kernel.org/r/20231218073849.35294-4-peter.hilber@opensynergy.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/timekeeping.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
+index 1749a712f72d1..b158cbef4d8dc 100644
+--- a/kernel/time/timekeeping.c
++++ b/kernel/time/timekeeping.c
+@@ -1261,10 +1261,8 @@ int get_device_system_crosststamp(int (*get_time_fn)
+ tk_core.timekeeper.offs_real);
+ base_raw = tk->tkr_raw.base;
+
+- nsec_real = timekeeping_cycles_to_ns(&tk->tkr_mono,
+- system_counterval.cycles);
+- nsec_raw = timekeeping_cycles_to_ns(&tk->tkr_raw,
+- system_counterval.cycles);
++ nsec_real = timekeeping_cycles_to_ns(&tk->tkr_mono, cycles);
++ nsec_raw = timekeeping_cycles_to_ns(&tk->tkr_raw, cycles);
+ } while (read_seqcount_retry(&tk_core.seq, seq));
+
+ xtstamp->sys_realtime = ktime_add_ns(base_real, nsec_real);
+--
+2.43.0
+
--- /dev/null
+From fe7dc20167ad31b4fc9cf9d4b1ed552a8c5bb6b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Dec 2023 08:38:39 +0100
+Subject: timekeeping: Fix cross-timestamp interpolation on counter wrap
+
+From: Peter Hilber <peter.hilber@opensynergy.com>
+
+[ Upstream commit 84dccadd3e2a3f1a373826ad71e5ced5e76b0c00 ]
+
+cycle_between() decides whether get_device_system_crosststamp() will
+interpolate for older counter readings.
+
+cycle_between() yields wrong results for a counter wrap-around where after
+< before < test, and for the case after < test < before.
+
+Fix the comparison logic.
+
+Fixes: 2c756feb18d9 ("time: Add history to cross timestamp interface supporting slower devices")
+Signed-off-by: Peter Hilber <peter.hilber@opensynergy.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: John Stultz <jstultz@google.com>
+Link: https://lore.kernel.org/r/20231218073849.35294-2-peter.hilber@opensynergy.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/timekeeping.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
+index 221c8c404973a..c168931c78e01 100644
+--- a/kernel/time/timekeeping.c
++++ b/kernel/time/timekeeping.c
+@@ -1186,7 +1186,7 @@ static bool cycle_between(u64 before, u64 test, u64 after)
+ {
+ if (test > before && test < after)
+ return true;
+- if (test < before && before > after)
++ if (before > after && (test > before || test < after))
+ return true;
+ return false;
+ }
+--
+2.43.0
+
--- /dev/null
+From a6410851a98ce33458402311fd6e10140784364c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Feb 2024 13:46:10 +0100
+Subject: tools/resolve_btfids: Fix cross-compilation to non-host endianness
+
+From: Viktor Malik <vmalik@redhat.com>
+
+[ Upstream commit 903fad4394666bc23975c93fb58f137ce64b5192 ]
+
+The .BTF_ids section is pre-filled with zeroed BTF ID entries during the
+build and afterwards patched by resolve_btfids with correct values.
+Since resolve_btfids always writes in host-native endianness, it relies
+on libelf to do the translation when the target ELF is cross-compiled to
+a different endianness (this was introduced in commit 61e8aeda9398
+("bpf: Fix libelf endian handling in resolv_btfids")).
+
+Unfortunately, the translation will corrupt the flags fields of SET8
+entries because these were written during vmlinux compilation and are in
+the correct endianness already. This will lead to numerous selftests
+failures such as:
+
+ $ sudo ./test_verifier 502 502
+ #502/p sleepable fentry accept FAIL
+ Failed to load prog 'Invalid argument'!
+ bpf_fentry_test1 is not sleepable
+ verification time 34 usec
+ stack depth 0
+ processed 0 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
+ Summary: 0 PASSED, 0 SKIPPED, 1 FAILED
+
+Since it's not possible to instruct libelf to translate just certain
+values, let's manually bswap the flags (both global and entry flags) in
+resolve_btfids when needed, so that libelf then translates everything
+correctly.
+
+Fixes: ef2c6f370a63 ("tools/resolve_btfids: Add support for 8-byte BTF sets")
+Signed-off-by: Viktor Malik <vmalik@redhat.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/7b6bff690919555574ce0f13d2a5996cacf7bf69.1707223196.git.vmalik@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/resolve_btfids/main.c | 35 +++++++++++++++++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+
+diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
+index cd42977c6a1f4..ef0764d6891e4 100644
+--- a/tools/bpf/resolve_btfids/main.c
++++ b/tools/bpf/resolve_btfids/main.c
+@@ -90,6 +90,14 @@
+
+ #define ADDR_CNT 100
+
++#if __BYTE_ORDER == __LITTLE_ENDIAN
++# define ELFDATANATIVE ELFDATA2LSB
++#elif __BYTE_ORDER == __BIG_ENDIAN
++# define ELFDATANATIVE ELFDATA2MSB
++#else
++# error "Unknown machine endianness!"
++#endif
++
+ struct btf_id {
+ struct rb_node rb_node;
+ char *name;
+@@ -117,6 +125,7 @@ struct object {
+ int idlist_shndx;
+ size_t strtabidx;
+ unsigned long idlist_addr;
++ int encoding;
+ } efile;
+
+ struct rb_root sets;
+@@ -320,6 +329,7 @@ static int elf_collect(struct object *obj)
+ {
+ Elf_Scn *scn = NULL;
+ size_t shdrstrndx;
++ GElf_Ehdr ehdr;
+ int idx = 0;
+ Elf *elf;
+ int fd;
+@@ -351,6 +361,13 @@ static int elf_collect(struct object *obj)
+ return -1;
+ }
+
++ if (gelf_getehdr(obj->efile.elf, &ehdr) == NULL) {
++ pr_err("FAILED cannot get ELF header: %s\n",
++ elf_errmsg(-1));
++ return -1;
++ }
++ obj->efile.encoding = ehdr.e_ident[EI_DATA];
++
+ /*
+ * Scan all the elf sections and look for save data
+ * from .BTF_ids section and symbols.
+@@ -681,6 +698,24 @@ static int sets_patch(struct object *obj)
+ */
+ BUILD_BUG_ON(set8->pairs != &set8->pairs[0].id);
+ qsort(set8->pairs, set8->cnt, sizeof(set8->pairs[0]), cmp_id);
++
++ /*
++ * When ELF endianness does not match endianness of the
++ * host, libelf will do the translation when updating
++ * the ELF. This, however, corrupts SET8 flags which are
++ * already in the target endianness. So, let's bswap
++ * them to the host endianness and libelf will then
++ * correctly translate everything.
++ */
++ if (obj->efile.encoding != ELFDATANATIVE) {
++ int i;
++
++ set8->flags = bswap_32(set8->flags);
++ for (i = 0; i < set8->cnt; i++) {
++ set8->pairs[i].flags =
++ bswap_32(set8->pairs[i].flags);
++ }
++ }
+ }
+
+ pr_debug("sorting addr %5lu: cnt %6d [%s]\n",
+--
+2.43.0
+
--- /dev/null
+From 72b86c24dc9a1df824ac377e05362a76c1ed6682 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Feb 2024 13:46:09 +0100
+Subject: tools/resolve_btfids: Refactor set sorting with types from btf_ids.h
+
+From: Viktor Malik <vmalik@redhat.com>
+
+[ Upstream commit 9707ac4fe2f5bac6406d2403f8b8a64d7b3d8e43 ]
+
+Instead of using magic offsets to access BTF ID set data, leverage types
+from btf_ids.h (btf_id_set and btf_id_set8) which define the actual
+layout of the data. Thanks to this change, set sorting should also
+continue working if the layout changes.
+
+This requires to sync the definition of 'struct btf_id_set8' from
+include/linux/btf_ids.h to tools/include/linux/btf_ids.h. We don't sync
+the rest of the file at the moment, b/c that would require to also sync
+multiple dependent headers and we don't need any other defs from
+btf_ids.h.
+
+Signed-off-by: Viktor Malik <vmalik@redhat.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Daniel Xu <dxu@dxuuu.xyz>
+Link: https://lore.kernel.org/bpf/ff7f062ddf6a00815fda3087957c4ce667f50532.1707223196.git.vmalik@redhat.com
+Stable-dep-of: 903fad439466 ("tools/resolve_btfids: Fix cross-compilation to non-host endianness")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/resolve_btfids/main.c | 35 ++++++++++++++++++++-------------
+ tools/include/linux/btf_ids.h | 9 +++++++++
+ 2 files changed, 30 insertions(+), 14 deletions(-)
+
+diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
+index 77058174082d7..cd42977c6a1f4 100644
+--- a/tools/bpf/resolve_btfids/main.c
++++ b/tools/bpf/resolve_btfids/main.c
+@@ -70,6 +70,7 @@
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <errno.h>
++#include <linux/btf_ids.h>
+ #include <linux/rbtree.h>
+ #include <linux/zalloc.h>
+ #include <linux/err.h>
+@@ -78,7 +79,7 @@
+ #include <subcmd/parse-options.h>
+
+ #define BTF_IDS_SECTION ".BTF_ids"
+-#define BTF_ID "__BTF_ID__"
++#define BTF_ID_PREFIX "__BTF_ID__"
+
+ #define BTF_STRUCT "struct"
+ #define BTF_UNION "union"
+@@ -161,7 +162,7 @@ static int eprintf(int level, int var, const char *fmt, ...)
+
+ static bool is_btf_id(const char *name)
+ {
+- return name && !strncmp(name, BTF_ID, sizeof(BTF_ID) - 1);
++ return name && !strncmp(name, BTF_ID_PREFIX, sizeof(BTF_ID_PREFIX) - 1);
+ }
+
+ static struct btf_id *btf_id__find(struct rb_root *root, const char *name)
+@@ -441,7 +442,7 @@ static int symbols_collect(struct object *obj)
+ * __BTF_ID__TYPE__vfs_truncate__0
+ * prefix = ^
+ */
+- prefix = name + sizeof(BTF_ID) - 1;
++ prefix = name + sizeof(BTF_ID_PREFIX) - 1;
+
+ /* struct */
+ if (!strncmp(prefix, BTF_STRUCT, sizeof(BTF_STRUCT) - 1)) {
+@@ -649,19 +650,18 @@ static int cmp_id(const void *pa, const void *pb)
+ static int sets_patch(struct object *obj)
+ {
+ Elf_Data *data = obj->efile.idlist;
+- int *ptr = data->d_buf;
+ struct rb_node *next;
+
+ next = rb_first(&obj->sets);
+ while (next) {
+- unsigned long addr, idx;
++ struct btf_id_set8 *set8;
++ struct btf_id_set *set;
++ unsigned long addr, off;
+ struct btf_id *id;
+- int *base;
+- int cnt;
+
+ id = rb_entry(next, struct btf_id, rb_node);
+ addr = id->addr[0];
+- idx = addr - obj->efile.idlist_addr;
++ off = addr - obj->efile.idlist_addr;
+
+ /* sets are unique */
+ if (id->addr_cnt != 1) {
+@@ -670,14 +670,21 @@ static int sets_patch(struct object *obj)
+ return -1;
+ }
+
+- idx = idx / sizeof(int);
+- base = &ptr[idx] + (id->is_set8 ? 2 : 1);
+- cnt = ptr[idx];
++ if (id->is_set) {
++ set = data->d_buf + off;
++ qsort(set->ids, set->cnt, sizeof(set->ids[0]), cmp_id);
++ } else {
++ set8 = data->d_buf + off;
++ /*
++ * Make sure id is at the beginning of the pairs
++ * struct, otherwise the below qsort would not work.
++ */
++ BUILD_BUG_ON(set8->pairs != &set8->pairs[0].id);
++ qsort(set8->pairs, set8->cnt, sizeof(set8->pairs[0]), cmp_id);
++ }
+
+ pr_debug("sorting addr %5lu: cnt %6d [%s]\n",
+- (idx + 1) * sizeof(int), cnt, id->name);
+-
+- qsort(base, cnt, id->is_set8 ? sizeof(uint64_t) : sizeof(int), cmp_id);
++ off, id->is_set ? set->cnt : set8->cnt, id->name);
+
+ next = rb_next(next);
+ }
+diff --git a/tools/include/linux/btf_ids.h b/tools/include/linux/btf_ids.h
+index 2f882d5cb30f5..72535f00572f6 100644
+--- a/tools/include/linux/btf_ids.h
++++ b/tools/include/linux/btf_ids.h
+@@ -8,6 +8,15 @@ struct btf_id_set {
+ u32 ids[];
+ };
+
++struct btf_id_set8 {
++ u32 cnt;
++ u32 flags;
++ struct {
++ u32 id;
++ u32 flags;
++ } pairs[];
++};
++
+ #ifdef CONFIG_DEBUG_INFO_BTF
+
+ #include <linux/compiler.h> /* for __PASTE */
+--
+2.43.0
+
--- /dev/null
+From 6f76eb9c1e95fbd0e04f91f6d8c741e48d2cc9ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 14:23:50 +0000
+Subject: udp: fix incorrect parameter validation in the udp_lib_getsockopt()
+ function
+
+From: Gavrilov Ilia <Ilia.Gavrilov@infotecs.ru>
+
+[ Upstream commit 4bb3ba7b74fceec6f558745b25a43c6521cf5506 ]
+
+The 'len' variable can't be negative when assigned the result of
+'min_t' because all 'min_t' parameters are cast to unsigned int,
+and then the minimum one is chosen.
+
+To fix the logic, check 'len' as read from 'optlen',
+where the types of relevant variables are (signed) int.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Gavrilov Ilia <Ilia.Gavrilov@infotecs.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/udp.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 87d759bab0012..7856b7a3e0ee9 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -2790,11 +2790,11 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
+ if (get_user(len, optlen))
+ return -EFAULT;
+
+- len = min_t(unsigned int, len, sizeof(int));
+-
+ if (len < 0)
+ return -EINVAL;
+
++ len = min_t(unsigned int, len, sizeof(int));
++
+ switch (optname) {
+ case UDP_CORK:
+ val = udp_test_bit(CORK, sk);
+--
+2.43.0
+
--- /dev/null
+From 6134e9364ac348eca22f1a7b8b04c40d876a017c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Feb 2024 13:27:23 -0500
+Subject: watchdog: stm32_iwdg: initialize default timeout
+
+From: Ben Wolsieffer <ben.wolsieffer@hefring.com>
+
+[ Upstream commit dbd7c0088b7f44aa0b9276ed3449df075a7b5b54 ]
+
+The driver never sets a default timeout value, therefore it is
+initialized to zero. When CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED is
+enabled, the watchdog is started during probe. The kernel is supposed to
+automatically ping the watchdog from this point until userspace takes
+over, but this does not happen if the configured timeout is zero. A zero
+timeout causes watchdog_need_worker() to return false, so the heartbeat
+worker does not run and the system therefore resets soon after the
+driver is probed.
+
+This patch fixes this by setting an arbitrary non-zero default timeout.
+The default could be read from the hardware instead, but I didn't see
+any reason to add this complexity.
+
+This has been tested on an STM32F746.
+
+Fixes: 85fdc63fe256 ("drivers: watchdog: stm32_iwdg: set WDOG_HW_RUNNING at probe")
+Signed-off-by: Ben Wolsieffer <ben.wolsieffer@hefring.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20240228182723.12855-1-ben.wolsieffer@hefring.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/stm32_iwdg.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c
+index 570a71509d2a9..78d51deab87aa 100644
+--- a/drivers/watchdog/stm32_iwdg.c
++++ b/drivers/watchdog/stm32_iwdg.c
+@@ -21,6 +21,8 @@
+ #include <linux/platform_device.h>
+ #include <linux/watchdog.h>
+
++#define DEFAULT_TIMEOUT 10
++
+ /* IWDG registers */
+ #define IWDG_KR 0x00 /* Key register */
+ #define IWDG_PR 0x04 /* Prescaler Register */
+@@ -249,6 +251,7 @@ static int stm32_iwdg_probe(struct platform_device *pdev)
+ wdd->parent = dev;
+ wdd->info = &stm32_iwdg_info;
+ wdd->ops = &stm32_iwdg_ops;
++ wdd->timeout = DEFAULT_TIMEOUT;
+ wdd->min_timeout = DIV_ROUND_UP((RLR_MIN + 1) * PR_MIN, wdt->rate);
+ wdd->max_hw_heartbeat_ms = ((RLR_MAX + 1) * wdt->data->max_prescaler *
+ 1000) / wdt->rate;
+--
+2.43.0
+
--- /dev/null
+From 34675629ca0aa60bca97517965ff1257356edaad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Dec 2023 13:29:01 +0200
+Subject: wifi: ath10k: fix NULL pointer dereference in
+ ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev()
+
+From: Xingyuan Mo <hdthky0@gmail.com>
+
+[ Upstream commit ad25ee36f00172f7d53242dc77c69fff7ced0755 ]
+
+We should check whether the WMI_TLV_TAG_STRUCT_MGMT_TX_COMPL_EVENT tlv is
+present before accessing it, otherwise a null pointer deference error will
+occur.
+
+Fixes: dc405152bb64 ("ath10k: handle mgmt tx completion event")
+Signed-off-by: Xingyuan Mo <hdthky0@gmail.com>
+Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://msgid.link/20231208043433.271449-1-hdthky0@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath10k/wmi-tlv.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+index 876410a47d1d2..4d5009604eee7 100644
+--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
++++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+@@ -844,6 +844,10 @@ ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev(struct ath10k *ar, struct sk_buff *skb,
+ }
+
+ ev = tb[WMI_TLV_TAG_STRUCT_MGMT_TX_COMPL_EVENT];
++ if (!ev) {
++ kfree(tb);
++ return -EPROTO;
++ }
+
+ arg->desc_id = ev->desc_id;
+ arg->status = ev->status;
+--
+2.43.0
+
--- /dev/null
+From 677d0a52a53cf7598071b286b88db26b03c34ccf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Feb 2024 10:35:47 +0800
+Subject: wifi: ath11k: initialize rx_mcs_80 and rx_mcs_160 before use
+
+From: Baochen Qiang <quic_bqiang@quicinc.com>
+
+[ Upstream commit b802e7b7e771dee3377d071418281f8b64d2d832 ]
+
+Currently in ath11k_peer_assoc_h_he() rx_mcs_80 and rx_mcs_160
+are used to calculate max_nss, see
+ if (support_160)
+ max_nss = min(rx_mcs_80, rx_mcs_160);
+ else
+ max_nss = rx_mcs_80;
+
+Kernel test robot complains on uninitialized symbols:
+drivers/net/wireless/ath/ath11k/mac.c:2321 ath11k_peer_assoc_h_he() error: uninitialized symbol 'rx_mcs_80'.
+drivers/net/wireless/ath/ath11k/mac.c:2321 ath11k_peer_assoc_h_he() error: uninitialized symbol 'rx_mcs_160'.
+drivers/net/wireless/ath/ath11k/mac.c:2323 ath11k_peer_assoc_h_he() error: uninitialized symbol 'rx_mcs_80'.
+
+This is because there are some code paths that never set them, so
+the assignment of max_nss can come from uninitialized variables.
+This could result in some unknown issues since a wrong peer_nss
+might be passed to firmware.
+
+Change to initialize them to an invalid value at the beginning. This
+makes sense because even max_nss gets an invalid value, due to either
+or both of them being invalid, we can get an valid peer_nss with
+following guard:
+ arg->peer_nss = min(sta->deflink.rx_nss, max_nss)
+
+Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23
+
+Fixes: 3db26ecf7114 ("ath11k: calculate the correct NSS of peer for HE capabilities")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202401311243.NyXwWZxP-lkp@intel.com/
+Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
+Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://msgid.link/20240202023547.11141-1-quic_bqiang@quicinc.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath11k/mac.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
+index 21c6b36dc6ebb..51fc77e93de5c 100644
+--- a/drivers/net/wireless/ath/ath11k/mac.c
++++ b/drivers/net/wireless/ath/ath11k/mac.c
+@@ -2112,6 +2112,8 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar,
+ mcs_160_map = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160);
+ mcs_80_map = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80);
+
++ /* Initialize rx_mcs_160 to 9 which is an invalid value */
++ rx_mcs_160 = 9;
+ if (support_160) {
+ for (i = 7; i >= 0; i--) {
+ u8 mcs_160 = (mcs_160_map >> (2 * i)) & 3;
+@@ -2123,6 +2125,8 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar,
+ }
+ }
+
++ /* Initialize rx_mcs_80 to 9 which is an invalid value */
++ rx_mcs_80 = 9;
+ for (i = 7; i >= 0; i--) {
+ u8 mcs_80 = (mcs_80_map >> (2 * i)) & 3;
+
+--
+2.43.0
+
--- /dev/null
+From 59399eb4123d3435a7e0df4802fec8224ecda0fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Jan 2024 15:02:17 +0100
+Subject: wifi: ath9k: delay all of ath9k_wmi_event_tasklet() until init is
+ complete
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Toke Høiland-Jørgensen <toke@redhat.com>
+
+[ Upstream commit 24355fcb0d4cbcb6ddda262596558e8cfba70f11 ]
+
+The ath9k_wmi_event_tasklet() used in ath9k_htc assumes that all the data
+structures have been fully initialised by the time it runs. However, because of
+the order in which things are initialised, this is not guaranteed to be the
+case, because the device is exposed to the USB subsystem before the ath9k driver
+initialisation is completed.
+
+We already committed a partial fix for this in commit:
+8b3046abc99e ("ath9k_htc: fix NULL pointer dereference at ath9k_htc_tx_get_packet()")
+
+However, that commit only aborted the WMI_TXSTATUS_EVENTID command in the event
+tasklet, pairing it with an "initialisation complete" bit in the TX struct. It
+seems syzbot managed to trigger the race for one of the other commands as well,
+so let's just move the existing synchronisation bit to cover the whole
+tasklet (setting it at the end of ath9k_htc_probe_device() instead of inside
+ath9k_tx_init()).
+
+Link: https://lore.kernel.org/r/ed1d2c66-1193-4c81-9542-d514c29ba8b8.bugreport@ubisectech.com
+Fixes: 8b3046abc99e ("ath9k_htc: fix NULL pointer dereference at ath9k_htc_tx_get_packet()")
+Reported-by: Ubisectech Sirius <bugreport@ubisectech.com>
+Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://msgid.link/20240126140218.1033443-1-toke@toke.dk
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/htc.h | 2 +-
+ drivers/net/wireless/ath/ath9k/htc_drv_init.c | 4 ++++
+ drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 4 ----
+ drivers/net/wireless/ath/ath9k/wmi.c | 10 ++++++----
+ 4 files changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
+index 237f4ec2cffd7..6c33e898b3000 100644
+--- a/drivers/net/wireless/ath/ath9k/htc.h
++++ b/drivers/net/wireless/ath/ath9k/htc.h
+@@ -306,7 +306,6 @@ struct ath9k_htc_tx {
+ DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM);
+ struct timer_list cleanup_timer;
+ spinlock_t tx_lock;
+- bool initialized;
+ };
+
+ struct ath9k_htc_tx_ctl {
+@@ -515,6 +514,7 @@ struct ath9k_htc_priv {
+ unsigned long ps_usecount;
+ bool ps_enabled;
+ bool ps_idle;
++ bool initialized;
+
+ #ifdef CONFIG_MAC80211_LEDS
+ enum led_brightness brightness;
+diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+index 96a3185a96d75..b014185373f34 100644
+--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
++++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+@@ -966,6 +966,10 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
+
+ htc_handle->drv_priv = priv;
+
++ /* Allow ath9k_wmi_event_tasklet() to operate. */
++ smp_wmb();
++ priv->initialized = true;
++
+ return 0;
+
+ err_init:
+diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+index d6a3f001dacb9..2fdd27885f543 100644
+--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
++++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+@@ -815,10 +815,6 @@ int ath9k_tx_init(struct ath9k_htc_priv *priv)
+ skb_queue_head_init(&priv->tx.data_vo_queue);
+ skb_queue_head_init(&priv->tx.tx_failed);
+
+- /* Allow ath9k_wmi_event_tasklet(WMI_TXSTATUS_EVENTID) to operate. */
+- smp_wmb();
+- priv->tx.initialized = true;
+-
+ return 0;
+ }
+
+diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
+index 1476b42b52a91..805ad31edba2b 100644
+--- a/drivers/net/wireless/ath/ath9k/wmi.c
++++ b/drivers/net/wireless/ath/ath9k/wmi.c
+@@ -155,6 +155,12 @@ void ath9k_wmi_event_tasklet(struct tasklet_struct *t)
+ }
+ spin_unlock_irqrestore(&wmi->wmi_lock, flags);
+
++ /* Check if ath9k_htc_probe_device() completed. */
++ if (!data_race(priv->initialized)) {
++ kfree_skb(skb);
++ continue;
++ }
++
+ hdr = (struct wmi_cmd_hdr *) skb->data;
+ cmd_id = be16_to_cpu(hdr->command_id);
+ wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
+@@ -169,10 +175,6 @@ void ath9k_wmi_event_tasklet(struct tasklet_struct *t)
+ &wmi->drv_priv->fatal_work);
+ break;
+ case WMI_TXSTATUS_EVENTID:
+- /* Check if ath9k_tx_init() completed. */
+- if (!data_race(priv->tx.initialized))
+- break;
+-
+ spin_lock_bh(&priv->tx.tx_lock);
+ if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) {
+ spin_unlock_bh(&priv->tx.tx_lock);
+--
+2.43.0
+
--- /dev/null
+From 5bc4097876b35153aebd93609c6d5aee959a7ddf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 31 Dec 2023 05:03:58 +0000
+Subject: wifi: b43: Disable QoS for bcm4331
+
+From: Rahul Rameshbabu <sergeantsagara@protonmail.com>
+
+[ Upstream commit 09795bded2e725443fe4a4803cae2079cdaf7b26 ]
+
+bcm4331 seems to not function correctly with QoS support. This may be due
+to issues with currently available firmware or potentially a device
+specific issue.
+
+When queues that are not of the default "best effort" priority are
+selected, traffic appears to not transmit out of the hardware while no
+errors are returned. This behavior is present among all the other priority
+queues: video, voice, and background. While this can be worked around by
+setting a kernel parameter, the default behavior is problematic for most
+users and may be difficult to debug. This patch offers a working out-of-box
+experience for bcm4331 users.
+
+Log of the issue (using ssh low-priority traffic as an example):
+ ssh -T -vvvv git@github.com
+ OpenSSH_9.6p1, OpenSSL 3.0.12 24 Oct 2023
+ debug1: Reading configuration data /etc/ssh/ssh_config
+ debug2: checking match for 'host * exec "/nix/store/q1c2flcykgr4wwg5a6h450hxbk4ch589-bash-5.2-p15/bin/bash -c '/nix/store/c015armnkhr6v18za0rypm7sh1i8js8w-gnupg-2.4.1/bin/gpg-connect-agent --quiet updatestartuptty /bye >/dev/null 2>&1'"' host github.com originally github.com
+ debug3: /etc/ssh/ssh_config line 5: matched 'host "github.com"'
+ debug1: Executing command: '/nix/store/q1c2flcykgr4wwg5a6h450hxbk4ch589-bash-5.2-p15/bin/bash -c '/nix/store/c015armnkhr6v18za0rypm7sh1i8js8w-gnupg-2.4.1/bin/gpg-connect-agent --quiet updatestartuptty /bye >/dev/null 2>&1''
+ debug3: command returned status 0
+ debug3: /etc/ssh/ssh_config line 5: matched 'exec "/nix/store/q1c2flcykgr4wwg5a6h450hxbk4ch589-bash-5.2-p15/bin/bash -c '/nix/store/c015armnkhr6v18za0r"'
+ debug2: match found
+ debug1: /etc/ssh/ssh_config line 9: Applying options for *
+ debug3: expanded UserKnownHostsFile '~/.ssh/known_hosts' -> '/home/binary-eater/.ssh/known_hosts'
+ debug3: expanded UserKnownHostsFile '~/.ssh/known_hosts2' -> '/home/binary-eater/.ssh/known_hosts2'
+ debug2: resolving "github.com" port 22
+ debug3: resolve_host: lookup github.com:22
+ debug3: channel_clear_timeouts: clearing
+ debug3: ssh_connect_direct: entering
+ debug1: Connecting to github.com [192.30.255.113] port 22.
+ debug3: set_sock_tos: set socket 3 IP_TOS 0x48
+
+Fixes: e6f5b934fba8 ("b43: Add QOS support")
+Signed-off-by: Rahul Rameshbabu <sergeantsagara@protonmail.com>
+Reviewed-by: Julian Calaby <julian.calaby@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20231231050300.122806-5-sergeantsagara@protonmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/b43/main.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c
+index c75f294ca1bc9..bdfa68cc7ee2a 100644
+--- a/drivers/net/wireless/broadcom/b43/main.c
++++ b/drivers/net/wireless/broadcom/b43/main.c
+@@ -2587,7 +2587,8 @@ static void b43_request_firmware(struct work_struct *work)
+
+ start_ieee80211:
+ wl->hw->queues = B43_QOS_QUEUE_NUM;
+- if (!modparam_qos || dev->fw.opensource)
++ if (!modparam_qos || dev->fw.opensource ||
++ dev->dev->chip_id == BCMA_CHIP_ID_BCM4331)
+ wl->hw->queues = 1;
+
+ err = ieee80211_register_hw(wl->hw);
+--
+2.43.0
+
--- /dev/null
+From dc9a84452fda48bac819f3a7be1a23bbbf368d1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 31 Dec 2023 05:03:51 +0000
+Subject: wifi: b43: Stop correct queue in DMA worker when QoS is disabled
+
+From: Rahul Rameshbabu <sergeantsagara@protonmail.com>
+
+[ Upstream commit 581c8967d66c4961076dbbee356834e9c6777184 ]
+
+When QoS is disabled, the queue priority value will not map to the correct
+ieee80211 queue since there is only one queue. Stop queue 0 when QoS is
+disabled to prevent trying to stop a non-existent queue and failing to stop
+the actual queue instantiated.
+
+Fixes: bad691946966 ("b43: avoid packet losses in the dma worker code.")
+Signed-off-by: Rahul Rameshbabu <sergeantsagara@protonmail.com>
+Reviewed-by: Julian Calaby <julian.calaby@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20231231050300.122806-4-sergeantsagara@protonmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/b43/main.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c
+index b2539a916fd04..c75f294ca1bc9 100644
+--- a/drivers/net/wireless/broadcom/b43/main.c
++++ b/drivers/net/wireless/broadcom/b43/main.c
+@@ -3603,7 +3603,7 @@ static void b43_tx_work(struct work_struct *work)
+ err = b43_dma_tx(dev, skb);
+ if (err == -ENOSPC) {
+ wl->tx_queue_stopped[queue_num] = true;
+- ieee80211_stop_queue(wl->hw, queue_num);
++ b43_stop_queue(dev, queue_num);
+ skb_queue_head(&wl->tx_queue[queue_num], skb);
+ break;
+ }
+@@ -3627,6 +3627,7 @@ static void b43_op_tx(struct ieee80211_hw *hw,
+ struct sk_buff *skb)
+ {
+ struct b43_wl *wl = hw_to_b43_wl(hw);
++ u16 skb_queue_mapping;
+
+ if (unlikely(skb->len < 2 + 2 + 6)) {
+ /* Too short, this can't be a valid frame. */
+@@ -3635,12 +3636,12 @@ static void b43_op_tx(struct ieee80211_hw *hw,
+ }
+ B43_WARN_ON(skb_shinfo(skb)->nr_frags);
+
+- skb_queue_tail(&wl->tx_queue[skb->queue_mapping], skb);
+- if (!wl->tx_queue_stopped[skb->queue_mapping]) {
++ skb_queue_mapping = skb_get_queue_mapping(skb);
++ skb_queue_tail(&wl->tx_queue[skb_queue_mapping], skb);
++ if (!wl->tx_queue_stopped[skb_queue_mapping])
+ ieee80211_queue_work(wl->hw, &wl->tx_work);
+- } else {
+- ieee80211_stop_queue(wl->hw, skb->queue_mapping);
+- }
++ else
++ b43_stop_queue(wl->current_dev, skb_queue_mapping);
+ }
+
+ static void b43_qos_params_upload(struct b43_wldev *dev,
+--
+2.43.0
+
--- /dev/null
+From 17fff3bf48fb4159bb1db264f0320c8400ed65c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 31 Dec 2023 05:03:33 +0000
+Subject: wifi: b43: Stop/wake correct queue in DMA Tx path when QoS is
+ disabled
+
+From: Rahul Rameshbabu <sergeantsagara@protonmail.com>
+
+[ Upstream commit 9636951e4468f02c72cc75a82dc65d003077edbc ]
+
+When QoS is disabled, the queue priority value will not map to the correct
+ieee80211 queue since there is only one queue. Stop/wake queue 0 when QoS
+is disabled to prevent trying to stop/wake a non-existent queue and failing
+to stop/wake the actual queue instantiated.
+
+Log of issue before change (with kernel parameter qos=0):
+ [ +5.112651] ------------[ cut here ]------------
+ [ +0.000005] WARNING: CPU: 7 PID: 25513 at net/mac80211/util.c:449 __ieee80211_wake_queue+0xd5/0x180 [mac80211]
+ [ +0.000067] Modules linked in: b43(O) snd_seq_dummy snd_hrtimer snd_seq snd_seq_device nft_chain_nat xt_MASQUERADE nf_nat xfrm_user xfrm_algo xt_addrtype overlay ccm af_packet amdgpu snd_hda_codec_cirrus snd_hda_codec_generic ledtrig_audio drm_exec amdxcp gpu_sched xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 ip6t_rpfilter ipt_rpfilter xt_pkttype xt_LOG nf_log_syslog xt_tcpudp nft_compat nf_tables nfnetlink sch_fq_codel btusb uinput iTCO_wdt ctr btrtl intel_pmc_bxt i915 intel_rapl_msr mei_hdcp mei_pxp joydev at24 watchdog btintel atkbd libps2 serio radeon btbcm vivaldi_fmap btmtk intel_rapl_common snd_hda_codec_hdmi bluetooth uvcvideo nls_iso8859_1 applesmc nls_cp437 x86_pkg_temp_thermal snd_hda_intel intel_powerclamp vfat videobuf2_vmalloc coretemp fat snd_intel_dspcfg crc32_pclmul uvc polyval_clmulni snd_intel_sdw_acpi loop videobuf2_memops snd_hda_codec tun drm_suballoc_helper polyval_generic drm_ttm_helper drm_buddy tap ecdh_generic videobuf2_v4l2 gf128mul macvlan ttm ghash_clmulni_intel ecc tg3
+ [ +0.000044] videodev bridge snd_hda_core rapl crc16 drm_display_helper cec mousedev snd_hwdep evdev intel_cstate bcm5974 hid_appleir videobuf2_common stp mac_hid libphy snd_pcm drm_kms_helper acpi_als mei_me intel_uncore llc mc snd_timer intel_gtt industrialio_triggered_buffer apple_mfi_fastcharge i2c_i801 mei snd lpc_ich agpgart ptp i2c_smbus thunderbolt apple_gmux i2c_algo_bit kfifo_buf video industrialio soundcore pps_core wmi tiny_power_button sbs sbshc button ac cordic bcma mac80211 cfg80211 ssb rfkill libarc4 kvm_intel kvm drm irqbypass fuse backlight firmware_class efi_pstore configfs efivarfs dmi_sysfs ip_tables x_tables autofs4 dm_crypt cbc encrypted_keys trusted asn1_encoder tee tpm rng_core input_leds hid_apple led_class hid_generic usbhid hid sd_mod t10_pi crc64_rocksoft crc64 crc_t10dif crct10dif_generic ahci libahci libata uhci_hcd ehci_pci ehci_hcd crct10dif_pclmul crct10dif_common sha512_ssse3 sha512_generic sha256_ssse3 sha1_ssse3 aesni_intel usbcore scsi_mod libaes crypto_simd cryptd scsi_common
+ [ +0.000055] usb_common rtc_cmos btrfs blake2b_generic libcrc32c crc32c_generic crc32c_intel xor raid6_pq dm_snapshot dm_bufio dm_mod dax [last unloaded: b43(O)]
+ [ +0.000009] CPU: 7 PID: 25513 Comm: irq/17-b43 Tainted: G W O 6.6.7 #1-NixOS
+ [ +0.000003] Hardware name: Apple Inc. MacBookPro8,3/Mac-942459F5819B171B, BIOS 87.0.0.0.0 06/13/2019
+ [ +0.000001] RIP: 0010:__ieee80211_wake_queue+0xd5/0x180 [mac80211]
+ [ +0.000046] Code: 00 45 85 e4 0f 85 9b 00 00 00 48 8d bd 40 09 00 00 f0 48 0f ba ad 48 09 00 00 00 72 0f 5b 5d 41 5c 41 5d 41 5e e9 cb 6d 3c d0 <0f> 0b 5b 5d 41 5c 41 5d 41 5e c3 cc cc cc cc 48 8d b4 16 94 00 00
+ [ +0.000002] RSP: 0018:ffffc90003c77d60 EFLAGS: 00010097
+ [ +0.000001] RAX: 0000000000000001 RBX: 0000000000000002 RCX: 0000000000000000
+ [ +0.000001] RDX: 0000000000000000 RSI: 0000000000000002 RDI: ffff88820b924900
+ [ +0.000002] RBP: ffff88820b924900 R08: ffffc90003c77d90 R09: 000000000003bfd0
+ [ +0.000001] R10: ffff88820b924900 R11: ffffc90003c77c68 R12: 0000000000000000
+ [ +0.000001] R13: 0000000000000000 R14: ffffc90003c77d90 R15: ffffffffc0fa6f40
+ [ +0.000001] FS: 0000000000000000(0000) GS:ffff88846fb80000(0000) knlGS:0000000000000000
+ [ +0.000001] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ [ +0.000001] CR2: 00007fafda7ae008 CR3: 000000046d220005 CR4: 00000000000606e0
+ [ +0.000002] Call Trace:
+ [ +0.000003] <TASK>
+ [ +0.000001] ? __ieee80211_wake_queue+0xd5/0x180 [mac80211]
+ [ +0.000044] ? __warn+0x81/0x130
+ [ +0.000005] ? __ieee80211_wake_queue+0xd5/0x180 [mac80211]
+ [ +0.000045] ? report_bug+0x171/0x1a0
+ [ +0.000004] ? handle_bug+0x41/0x70
+ [ +0.000004] ? exc_invalid_op+0x17/0x70
+ [ +0.000003] ? asm_exc_invalid_op+0x1a/0x20
+ [ +0.000005] ? __ieee80211_wake_queue+0xd5/0x180 [mac80211]
+ [ +0.000043] ieee80211_wake_queue+0x4a/0x80 [mac80211]
+ [ +0.000044] b43_dma_handle_txstatus+0x29c/0x3a0 [b43]
+ [ +0.000016] ? __pfx_irq_thread_fn+0x10/0x10
+ [ +0.000002] b43_handle_txstatus+0x61/0x80 [b43]
+ [ +0.000012] b43_interrupt_thread_handler+0x3f9/0x6b0 [b43]
+ [ +0.000011] irq_thread_fn+0x23/0x60
+ [ +0.000002] irq_thread+0xfe/0x1c0
+ [ +0.000002] ? __pfx_irq_thread_dtor+0x10/0x10
+ [ +0.000001] ? __pfx_irq_thread+0x10/0x10
+ [ +0.000001] kthread+0xe8/0x120
+ [ +0.000003] ? __pfx_kthread+0x10/0x10
+ [ +0.000003] ret_from_fork+0x34/0x50
+ [ +0.000002] ? __pfx_kthread+0x10/0x10
+ [ +0.000002] ret_from_fork_asm+0x1b/0x30
+ [ +0.000004] </TASK>
+ [ +0.000001] ---[ end trace 0000000000000000 ]---
+
+ [ +0.000065] ------------[ cut here ]------------
+ [ +0.000001] WARNING: CPU: 0 PID: 56077 at net/mac80211/util.c:514 __ieee80211_stop_queue+0xcc/0xe0 [mac80211]
+ [ +0.000077] Modules linked in: b43(O) snd_seq_dummy snd_hrtimer snd_seq snd_seq_device nft_chain_nat xt_MASQUERADE nf_nat xfrm_user xfrm_algo xt_addrtype overlay ccm af_packet amdgpu snd_hda_codec_cirrus snd_hda_codec_generic ledtrig_audio drm_exec amdxcp gpu_sched xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 ip6t_rpfilter ipt_rpfilter xt_pkttype xt_LOG nf_log_syslog xt_tcpudp nft_compat nf_tables nfnetlink sch_fq_codel btusb uinput iTCO_wdt ctr btrtl intel_pmc_bxt i915 intel_rapl_msr mei_hdcp mei_pxp joydev at24 watchdog btintel atkbd libps2 serio radeon btbcm vivaldi_fmap btmtk intel_rapl_common snd_hda_codec_hdmi bluetooth uvcvideo nls_iso8859_1 applesmc nls_cp437 x86_pkg_temp_thermal snd_hda_intel intel_powerclamp vfat videobuf2_vmalloc coretemp fat snd_intel_dspcfg crc32_pclmul uvc polyval_clmulni snd_intel_sdw_acpi loop videobuf2_memops snd_hda_codec tun drm_suballoc_helper polyval_generic drm_ttm_helper drm_buddy tap ecdh_generic videobuf2_v4l2 gf128mul macvlan ttm ghash_clmulni_intel ecc tg3
+ [ +0.000073] videodev bridge snd_hda_core rapl crc16 drm_display_helper cec mousedev snd_hwdep evdev intel_cstate bcm5974 hid_appleir videobuf2_common stp mac_hid libphy snd_pcm drm_kms_helper acpi_als mei_me intel_uncore llc mc snd_timer intel_gtt industrialio_triggered_buffer apple_mfi_fastcharge i2c_i801 mei snd lpc_ich agpgart ptp i2c_smbus thunderbolt apple_gmux i2c_algo_bit kfifo_buf video industrialio soundcore pps_core wmi tiny_power_button sbs sbshc button ac cordic bcma mac80211 cfg80211 ssb rfkill libarc4 kvm_intel kvm drm irqbypass fuse backlight firmware_class efi_pstore configfs efivarfs dmi_sysfs ip_tables x_tables autofs4 dm_crypt cbc encrypted_keys trusted asn1_encoder tee tpm rng_core input_leds hid_apple led_class hid_generic usbhid hid sd_mod t10_pi crc64_rocksoft crc64 crc_t10dif crct10dif_generic ahci libahci libata uhci_hcd ehci_pci ehci_hcd crct10dif_pclmul crct10dif_common sha512_ssse3 sha512_generic sha256_ssse3 sha1_ssse3 aesni_intel usbcore scsi_mod libaes crypto_simd cryptd scsi_common
+ [ +0.000084] usb_common rtc_cmos btrfs blake2b_generic libcrc32c crc32c_generic crc32c_intel xor raid6_pq dm_snapshot dm_bufio dm_mod dax [last unloaded: b43]
+ [ +0.000012] CPU: 0 PID: 56077 Comm: kworker/u16:17 Tainted: G W O 6.6.7 #1-NixOS
+ [ +0.000003] Hardware name: Apple Inc. MacBookPro8,3/Mac-942459F5819B171B, BIOS 87.0.0.0.0 06/13/2019
+ [ +0.000001] Workqueue: phy7 b43_tx_work [b43]
+ [ +0.000019] RIP: 0010:__ieee80211_stop_queue+0xcc/0xe0 [mac80211]
+ [ +0.000076] Code: 74 11 48 8b 78 08 0f b7 d6 89 e9 4c 89 e6 e8 ab f4 00 00 65 ff 0d 9c b7 34 3f 0f 85 55 ff ff ff 0f 1f 44 00 00 e9 4b ff ff ff <0f> 0b 5b 5d 41 5c 41 5d c3 cc cc cc cc 0f 1f 80 00 00 00 00 90 90
+ [ +0.000002] RSP: 0000:ffffc90004157d50 EFLAGS: 00010097
+ [ +0.000002] RAX: 0000000000000001 RBX: 0000000000000002 RCX: 0000000000000000
+ [ +0.000002] RDX: 0000000000000000 RSI: 0000000000000002 RDI: ffff8882d65d0900
+ [ +0.000002] RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000001
+ [ +0.000001] R10: 00000000000000ff R11: ffff88814d0155a0 R12: ffff8882d65d0900
+ [ +0.000002] R13: 0000000000000000 R14: ffff8881002d2800 R15: 00000000000000d0
+ [ +0.000002] FS: 0000000000000000(0000) GS:ffff88846f800000(0000) knlGS:0000000000000000
+ [ +0.000003] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ [ +0.000002] CR2: 00007f2e8c10c880 CR3: 0000000385b66005 CR4: 00000000000606f0
+ [ +0.000002] Call Trace:
+ [ +0.000001] <TASK>
+ [ +0.000001] ? __ieee80211_stop_queue+0xcc/0xe0 [mac80211]
+ [ +0.000075] ? __warn+0x81/0x130
+ [ +0.000004] ? __ieee80211_stop_queue+0xcc/0xe0 [mac80211]
+ [ +0.000075] ? report_bug+0x171/0x1a0
+ [ +0.000005] ? handle_bug+0x41/0x70
+ [ +0.000003] ? exc_invalid_op+0x17/0x70
+ [ +0.000004] ? asm_exc_invalid_op+0x1a/0x20
+ [ +0.000004] ? __ieee80211_stop_queue+0xcc/0xe0 [mac80211]
+ [ +0.000076] ieee80211_stop_queue+0x36/0x50 [mac80211]
+ [ +0.000077] b43_dma_tx+0x550/0x780 [b43]
+ [ +0.000023] b43_tx_work+0x90/0x130 [b43]
+ [ +0.000018] process_one_work+0x174/0x340
+ [ +0.000003] worker_thread+0x27b/0x3a0
+ [ +0.000004] ? __pfx_worker_thread+0x10/0x10
+ [ +0.000002] kthread+0xe8/0x120
+ [ +0.000003] ? __pfx_kthread+0x10/0x10
+ [ +0.000004] ret_from_fork+0x34/0x50
+ [ +0.000002] ? __pfx_kthread+0x10/0x10
+ [ +0.000003] ret_from_fork_asm+0x1b/0x30
+ [ +0.000006] </TASK>
+ [ +0.000001] ---[ end trace 0000000000000000 ]---
+
+Fixes: e6f5b934fba8 ("b43: Add QOS support")
+Signed-off-by: Rahul Rameshbabu <sergeantsagara@protonmail.com>
+Reviewed-by: Julian Calaby <julian.calaby@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20231231050300.122806-2-sergeantsagara@protonmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/b43/b43.h | 16 ++++++++++++++++
+ drivers/net/wireless/broadcom/b43/dma.c | 4 ++--
+ 2 files changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/broadcom/b43/b43.h b/drivers/net/wireless/broadcom/b43/b43.h
+index 67b4bac048e58..c0d8fc0b22fb2 100644
+--- a/drivers/net/wireless/broadcom/b43/b43.h
++++ b/drivers/net/wireless/broadcom/b43/b43.h
+@@ -1082,6 +1082,22 @@ static inline bool b43_using_pio_transfers(struct b43_wldev *dev)
+ return dev->__using_pio_transfers;
+ }
+
++static inline void b43_wake_queue(struct b43_wldev *dev, int queue_prio)
++{
++ if (dev->qos_enabled)
++ ieee80211_wake_queue(dev->wl->hw, queue_prio);
++ else
++ ieee80211_wake_queue(dev->wl->hw, 0);
++}
++
++static inline void b43_stop_queue(struct b43_wldev *dev, int queue_prio)
++{
++ if (dev->qos_enabled)
++ ieee80211_stop_queue(dev->wl->hw, queue_prio);
++ else
++ ieee80211_stop_queue(dev->wl->hw, 0);
++}
++
+ /* Message printing */
+ __printf(2, 3) void b43info(struct b43_wl *wl, const char *fmt, ...);
+ __printf(2, 3) void b43err(struct b43_wl *wl, const char *fmt, ...);
+diff --git a/drivers/net/wireless/broadcom/b43/dma.c b/drivers/net/wireless/broadcom/b43/dma.c
+index 9a7c62bd5e431..cfaf2f9d67b22 100644
+--- a/drivers/net/wireless/broadcom/b43/dma.c
++++ b/drivers/net/wireless/broadcom/b43/dma.c
+@@ -1399,7 +1399,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
+ should_inject_overflow(ring)) {
+ /* This TX ring is full. */
+ unsigned int skb_mapping = skb_get_queue_mapping(skb);
+- ieee80211_stop_queue(dev->wl->hw, skb_mapping);
++ b43_stop_queue(dev, skb_mapping);
+ dev->wl->tx_queue_stopped[skb_mapping] = true;
+ ring->stopped = true;
+ if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
+@@ -1570,7 +1570,7 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
+ } else {
+ /* If the driver queue is running wake the corresponding
+ * mac80211 queue. */
+- ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);
++ b43_wake_queue(dev, ring->queue_prio);
+ if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
+ b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index);
+ }
+--
+2.43.0
+
--- /dev/null
+From 1e5f2e0844a97eb15bed6bb0a884bea47a103bfb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 31 Dec 2023 05:03:45 +0000
+Subject: wifi: b43: Stop/wake correct queue in PIO Tx path when QoS is
+ disabled
+
+From: Rahul Rameshbabu <sergeantsagara@protonmail.com>
+
+[ Upstream commit 77135a38f6c2f950d2306ac3d37cbb407e6243f2 ]
+
+When QoS is disabled, the queue priority value will not map to the correct
+ieee80211 queue since there is only one queue. Stop/wake queue 0 when QoS
+is disabled to prevent trying to stop/wake a non-existent queue and failing
+to stop/wake the actual queue instantiated.
+
+Fixes: 5100d5ac81b9 ("b43: Add PIO support for PCMCIA devices")
+Signed-off-by: Rahul Rameshbabu <sergeantsagara@protonmail.com>
+Reviewed-by: Julian Calaby <julian.calaby@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20231231050300.122806-3-sergeantsagara@protonmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/b43/pio.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/broadcom/b43/pio.c b/drivers/net/wireless/broadcom/b43/pio.c
+index 8c28a9250cd19..cc19b589fa70d 100644
+--- a/drivers/net/wireless/broadcom/b43/pio.c
++++ b/drivers/net/wireless/broadcom/b43/pio.c
+@@ -525,7 +525,7 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
+ if (total_len > (q->buffer_size - q->buffer_used)) {
+ /* Not enough memory on the queue. */
+ err = -EBUSY;
+- ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
++ b43_stop_queue(dev, skb_get_queue_mapping(skb));
+ q->stopped = true;
+ goto out;
+ }
+@@ -552,7 +552,7 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
+ if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) ||
+ (q->free_packet_slots == 0)) {
+ /* The queue is full. */
+- ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
++ b43_stop_queue(dev, skb_get_queue_mapping(skb));
+ q->stopped = true;
+ }
+
+@@ -587,7 +587,7 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
+ list_add(&pack->list, &q->packets_list);
+
+ if (q->stopped) {
+- ieee80211_wake_queue(dev->wl->hw, q->queue_prio);
++ b43_wake_queue(dev, q->queue_prio);
+ q->stopped = false;
+ }
+ }
+--
+2.43.0
+
--- /dev/null
+From da515e85aceb004ebe723869496e16a5e3e5ecbc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Feb 2024 11:05:37 +0100
+Subject: wifi: brcmsmac: avoid function pointer casts
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit e1ea6db35fc3ba5ff063f097385e9f7a88c25356 ]
+
+An old cleanup went a little too far and causes a warning with clang-16
+and higher as it breaks control flow integrity (KCFI) rules:
+
+drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c:64:34: error: cast from 'void (*)(struct brcms_phy *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+ 64 | brcms_init_timer(physhim->wl, (void (*)(void *))fn,
+ | ^~~~~~~~~~~~~~~~~~~~
+
+Change this one instance back to passing a void pointer so it can be
+used with the timer callback interface.
+
+Fixes: d89a4c80601d ("staging: brcm80211: removed void * from softmac phy")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20240213100548.457854-1-arnd@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c | 3 ++-
+ drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c | 5 ++---
+ drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.h | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c
+index ccc621b8ed9f2..4a1fe982a948e 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c
+@@ -383,8 +383,9 @@ struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp)
+ return sh;
+ }
+
+-static void wlc_phy_timercb_phycal(struct brcms_phy *pi)
++static void wlc_phy_timercb_phycal(void *ptr)
+ {
++ struct brcms_phy *pi = ptr;
+ uint delay = 5;
+
+ if (PHY_PERICAL_MPHASE_PENDING(pi)) {
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c
+index a0de5db0cd646..b723817915365 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c
+@@ -57,12 +57,11 @@ void wlc_phy_shim_detach(struct phy_shim_info *physhim)
+ }
+
+ struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
+- void (*fn)(struct brcms_phy *pi),
++ void (*fn)(void *pi),
+ void *arg, const char *name)
+ {
+ return (struct wlapi_timer *)
+- brcms_init_timer(physhim->wl, (void (*)(void *))fn,
+- arg, name);
++ brcms_init_timer(physhim->wl, fn, arg, name);
+ }
+
+ void wlapi_free_timer(struct wlapi_timer *t)
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.h b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.h
+index dd8774717adee..27d0934e600ed 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.h
+@@ -131,7 +131,7 @@ void wlc_phy_shim_detach(struct phy_shim_info *physhim);
+
+ /* PHY to WL utility functions */
+ struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
+- void (*fn)(struct brcms_phy *pi),
++ void (*fn)(void *pi),
+ void *arg, const char *name);
+ void wlapi_free_timer(struct wlapi_timer *t);
+ void wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic);
+--
+2.43.0
+
--- /dev/null
+From d5bc2d90118e9b063a5502101d0d5fc47bde6771 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 Jan 2024 08:53:53 +0200
+Subject: wifi: iwlwifi: dbg-tlv: ensure NUL termination
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit ea1d166fae14e05d49ffb0ea9fcd4658f8d3dcea ]
+
+The iwl_fw_ini_debug_info_tlv is used as a string, so we must
+ensure the string is terminated correctly before using it.
+
+Fixes: a9248de42464 ("iwlwifi: dbg_ini: add TLV allocation new API support")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Reviewed-by: Gregory Greenman <gregory.greenman@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://msgid.link/20240128084842.be15e858ee89.Ibff93429cf999eafc7b26f3eef4c055dc84984a0@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+index 5979d904bbbd2..677c9e0b46f10 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+@@ -103,6 +103,12 @@ static int iwl_dbg_tlv_alloc_debug_info(struct iwl_trans *trans,
+ if (le32_to_cpu(tlv->length) != sizeof(*debug_info))
+ return -EINVAL;
+
++ /* we use this as a string, ensure input was NUL terminated */
++ if (strnlen(debug_info->debug_cfg_name,
++ sizeof(debug_info->debug_cfg_name)) ==
++ sizeof(debug_info->debug_cfg_name))
++ return -EINVAL;
++
+ IWL_DEBUG_FW(trans, "WRT: Loading debug cfg: %s\n",
+ debug_info->debug_cfg_name);
+
+--
+2.43.0
+
--- /dev/null
+From bf93c6d3683218611df9669f1c63e1b863cfdb89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Jan 2024 21:21:49 +0200
+Subject: wifi: iwlwifi: fix EWRD table validity check
+
+From: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+
+[ Upstream commit c8d8f3911135921ace8e939ea0956b55f74bf8a0 ]
+
+EWRD ACPI table contains up to 3 additional sar profiles.
+According to the BIOS spec, the table contains a n_profile
+variable indicating how many additional profiles exist in the
+table.
+Currently we check that n_profiles is not <= 0.
+But according to the BIOS spec, 0 is a valid value,
+and it can't be < 0 anyway because we receive that from ACPI as
+an unsigned integer.
+
+Fixes: 39c1a9728f93 ("iwlwifi: refactor the SAR tables from mvm to acpi")
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Reviewed-by: Gregory Greenman <gregory.greenman@intel.com>
+Link: https://msgid.link/20240129211905.448ea2f40814.Iffd2aadf8e8693e6cb599bee0406a800a0c1e081@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
+index f5fcc547de391..235963e1d7a9a 100644
+--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
++++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
+@@ -725,7 +725,7 @@ int iwl_sar_get_ewrd_table(struct iwl_fw_runtime *fwrt)
+ * from index 1, so the maximum value allowed here is
+ * ACPI_SAR_PROFILES_NUM - 1.
+ */
+- if (n_profiles <= 0 || n_profiles >= ACPI_SAR_PROFILE_NUM) {
++ if (n_profiles >= ACPI_SAR_PROFILE_NUM) {
+ ret = -EINVAL;
+ goto out_free;
+ }
+--
+2.43.0
+
--- /dev/null
+From 4699f661828a9ab448530426c00da0e6a1557a6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Feb 2024 18:02:09 +0200
+Subject: wifi: iwlwifi: mvm: don't set replay counters to 0xff
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit d5bd4041cd70faf26fc9a54bd6f172537bbe77f3 ]
+
+The firmware (later) actually uses the values even for keys
+that are invalid as far as the host is concerned, later in
+rekeying, and then only sets the low 48 bits since the PNs
+are only 48 bits over the air. It does, however, compare the
+full 64 bits later, obviously causing problems.
+
+Remove the memset and use kzalloc instead to avoid any old
+heap data leaking to the firmware. We already init all the
+other fields in the struct anyway. This leaves the data set
+to zero for any unused fields, so the firmware can look at
+them safely even if they're not used right now.
+
+Fixes: 79e561f0f05a ("iwlwifi: mvm: d3: implement RSC command version 5")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://msgid.link/20240206175739.462101146fef.I10f3855b99417af4247cff04af78dcbc6cb75c9c@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+index 2748459d12279..88f4f429d875c 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+@@ -461,12 +461,10 @@ static int iwl_mvm_wowlan_config_rsc_tsc(struct iwl_mvm *mvm,
+ struct wowlan_key_rsc_v5_data data = {};
+ int i;
+
+- data.rsc = kmalloc(sizeof(*data.rsc), GFP_KERNEL);
++ data.rsc = kzalloc(sizeof(*data.rsc), GFP_KERNEL);
+ if (!data.rsc)
+ return -ENOMEM;
+
+- memset(data.rsc, 0xff, sizeof(*data.rsc));
+-
+ for (i = 0; i < ARRAY_SIZE(data.rsc->mcast_key_id_map); i++)
+ data.rsc->mcast_key_id_map[i] =
+ IWL_MCAST_KEY_MAP_INVALID;
+--
+2.43.0
+
--- /dev/null
+From 2308504bb1ba0d9964777a22464a4ed311957c57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 Jan 2024 08:53:48 +0200
+Subject: wifi: iwlwifi: mvm: report beacon protection failures
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 91380f768d7f6e3d003755defa792e9a00a1444a ]
+
+Andrei reports that we just silently drop beacons after we
+report the key counters, but never report to userspace, so
+wpa_supplicant cannot send the WNM action frame. Fix that.
+
+Fixes: b1fdc2505abc ("iwlwifi: mvm: advertise BIGTK client support if available")
+Reported-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Reviewed-by: Gregory Greenman <gregory.greenman@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://msgid.link/20240128084842.7d855442cdce.Iba90b26f893dc8c49bfb8be65373cd0a138af12c@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 26 +++++++++++--------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+index f268a31ce26d9..105f283b777d2 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+@@ -299,6 +299,7 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
+ u32 status,
+ struct ieee80211_rx_status *stats)
+ {
++ struct wireless_dev *wdev;
+ struct iwl_mvm_sta *mvmsta;
+ struct iwl_mvm_vif *mvmvif;
+ u8 keyid;
+@@ -320,9 +321,15 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
+ if (!ieee80211_is_beacon(hdr->frame_control))
+ return 0;
+
++ if (!sta)
++ return -1;
++
++ mvmsta = iwl_mvm_sta_from_mac80211(sta);
++ mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
++
+ /* key mismatch - will also report !MIC_OK but we shouldn't count it */
+ if (!(status & IWL_RX_MPDU_STATUS_KEY_VALID))
+- return -1;
++ goto report;
+
+ /* good cases */
+ if (likely(status & IWL_RX_MPDU_STATUS_MIC_OK &&
+@@ -331,13 +338,6 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
+ return 0;
+ }
+
+- if (!sta)
+- return -1;
+-
+- mvmsta = iwl_mvm_sta_from_mac80211(sta);
+-
+- mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
+-
+ /*
+ * both keys will have the same cipher and MIC length, use
+ * whichever one is available
+@@ -346,11 +346,11 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
+ if (!key) {
+ key = rcu_dereference(mvmvif->bcn_prot.keys[1]);
+ if (!key)
+- return -1;
++ goto report;
+ }
+
+ if (len < key->icv_len + IEEE80211_GMAC_PN_LEN + 2)
+- return -1;
++ goto report;
+
+ /* get the real key ID */
+ keyid = frame[len - key->icv_len - IEEE80211_GMAC_PN_LEN - 2];
+@@ -364,7 +364,7 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
+ return -1;
+ key = rcu_dereference(mvmvif->bcn_prot.keys[keyid - 6]);
+ if (!key)
+- return -1;
++ goto report;
+ }
+
+ /* Report status to mac80211 */
+@@ -372,6 +372,10 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
+ ieee80211_key_mic_failure(key);
+ else if (status & IWL_RX_MPDU_STATUS_REPLAY_ERROR)
+ ieee80211_key_replay(key);
++report:
++ wdev = ieee80211_vif_to_wdev(mvmsta->vif);
++ if (wdev->netdev)
++ cfg80211_rx_unprot_mlme_mgmt(wdev->netdev, (void *)hdr, len);
+
+ return -1;
+ }
+--
+2.43.0
+
--- /dev/null
+From 0505544d4acdaf769e12419da74e9a3dcd771eb0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Jan 2024 15:53:34 +0800
+Subject: wifi: libertas: fix some memleaks in lbs_allocate_cmd_buffer()
+
+From: Zhipeng Lu <alexious@zju.edu.cn>
+
+[ Upstream commit 5f0e4aede01cb01fa633171f0533affd25328c3a ]
+
+In the for statement of lbs_allocate_cmd_buffer(), if the allocation of
+cmdarray[i].cmdbuf fails, both cmdarray and cmdarray[i].cmdbuf needs to
+be freed. Otherwise, there will be memleaks in lbs_allocate_cmd_buffer().
+
+Fixes: 876c9d3aeb98 ("[PATCH] Marvell Libertas 8388 802.11b/g USB driver")
+Signed-off-by: Zhipeng Lu <alexious@zju.edu.cn>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20240126075336.2825608-1-alexious@zju.edu.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/libertas/cmd.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/libertas/cmd.c b/drivers/net/wireless/marvell/libertas/cmd.c
+index 104d2b6dc9af6..5a525da434c28 100644
+--- a/drivers/net/wireless/marvell/libertas/cmd.c
++++ b/drivers/net/wireless/marvell/libertas/cmd.c
+@@ -1132,7 +1132,7 @@ int lbs_allocate_cmd_buffer(struct lbs_private *priv)
+ if (!cmdarray[i].cmdbuf) {
+ lbs_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n");
+ ret = -1;
+- goto done;
++ goto free_cmd_array;
+ }
+ }
+
+@@ -1140,8 +1140,17 @@ int lbs_allocate_cmd_buffer(struct lbs_private *priv)
+ init_waitqueue_head(&cmdarray[i].cmdwait_q);
+ lbs_cleanup_and_insert_cmd(priv, &cmdarray[i]);
+ }
+- ret = 0;
++ return 0;
+
++free_cmd_array:
++ for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
++ if (cmdarray[i].cmdbuf) {
++ kfree(cmdarray[i].cmdbuf);
++ cmdarray[i].cmdbuf = NULL;
++ }
++ }
++ kfree(priv->cmd_array);
++ priv->cmd_array = NULL;
+ done:
+ return ret;
+ }
+--
+2.43.0
+
--- /dev/null
+From 73861c4eba338bb0240cb5b5a4dbbc42865edc28 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Sep 2023 11:02:15 +0800
+Subject: wifi: mwifiex: debugfs: Drop unnecessary error check for
+ debugfs_create_dir()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 50180c7f8e3de7c2d87f619131776598fcb1478d ]
+
+debugfs_create_dir() returns ERR_PTR and never return NULL.
+
+As Russell suggested, this patch removes the error checking for
+debugfs_create_dir(). This is because the DebugFS kernel API is developed
+in a way that the caller can safely ignore the errors that occur during
+the creation of DebugFS nodes. The debugfs APIs have a IS_ERR() judge in
+start_creating() which can handle it gracefully. So these checks are
+unnecessary.
+
+Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Suggested-by: Russell King (Oracle) <linux@armlinux.org.uk>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20230903030216.1509013-3-ruanjinjie@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/mwifiex/debugfs.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/debugfs.c b/drivers/net/wireless/marvell/mwifiex/debugfs.c
+index 63f232c723374..55ca5b287fe7f 100644
+--- a/drivers/net/wireless/marvell/mwifiex/debugfs.c
++++ b/drivers/net/wireless/marvell/mwifiex/debugfs.c
+@@ -964,9 +964,6 @@ mwifiex_dev_debugfs_init(struct mwifiex_private *priv)
+ priv->dfs_dev_dir = debugfs_create_dir(priv->netdev->name,
+ mwifiex_dfs_dir);
+
+- if (!priv->dfs_dev_dir)
+- return;
+-
+ MWIFIEX_DFS_ADD_FILE(info);
+ MWIFIEX_DFS_ADD_FILE(debug);
+ MWIFIEX_DFS_ADD_FILE(getlog);
+--
+2.43.0
+
--- /dev/null
+From 9f45361559ab0f79af7f56aa0acc23522bc0e86b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jan 2024 17:36:27 +0100
+Subject: wifi: rtl8xxxu: add cancel_work_sync() for c2hcmd_work
+
+From: Martin Kaistra <martin.kaistra@linutronix.de>
+
+[ Upstream commit 1213acb478a7181cd73eeaf00db430f1e45b1361 ]
+
+The workqueue might still be running, when the driver is stopped. To
+avoid a use-after-free, call cancel_work_sync() in rtl8xxxu_stop().
+
+Fixes: e542e66b7c2e ("rtl8xxxu: add bluetooth co-existence support for single antenna")
+Signed-off-by: Martin Kaistra <martin.kaistra@linutronix.de>
+Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20240111163628.320697-2-martin.kaistra@linutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+index 6dd5ec1e4d8c3..ccac47dd781d6 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+@@ -6542,6 +6542,7 @@ static void rtl8xxxu_stop(struct ieee80211_hw *hw)
+ if (priv->usb_interrupts)
+ rtl8xxxu_write32(priv, REG_USB_HIMR, 0);
+
++ cancel_work_sync(&priv->c2hcmd_work);
+ cancel_delayed_work_sync(&priv->ra_watchdog);
+
+ rtl8xxxu_free_rx_resources(priv);
+--
+2.43.0
+
--- /dev/null
+From 41a8a33a1253347fa1820a1d922ddf83555964e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Mar 2024 00:35:09 +0200
+Subject: wifi: rtw88: 8821c: Fix beacon loss and disconnect
+
+From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
+
+[ Upstream commit e1dfa21427baeb813f9a2f9ceab6b7d32c3ca425 ]
+
+Tenda U9 V2.0, which contains RTL8811CU, is practically unusable because
+of frequent disconnections:
+
+Feb 23 14:46:45 ideapad2 wpa_supplicant[427]: wlp3s0f3u2: CTRL-EVENT-BEACON-LOSS
+Feb 23 14:46:46 ideapad2 wpa_supplicant[427]: wlp3s0f3u2: CTRL-EVENT-DISCONNECTED
+ bssid=90:55:de:__:__:__ reason=4 locally_generated=1
+
+Feb 23 14:46:52 ideapad2 wpa_supplicant[427]: wlp3s0f3u2: CTRL-EVENT-CONNECTED
+ - Connection to 90:55:de:__:__:__ completed [id=0 id_str=]
+Feb 23 14:46:54 ideapad2 wpa_supplicant[427]: wlp3s0f3u2: CTRL-EVENT-BEACON-LOSS
+Feb 23 14:46:55 ideapad2 wpa_supplicant[427]: wlp3s0f3u2: CTRL-EVENT-DISCONNECTED
+ bssid=90:55:de:__:__:__ reason=4 locally_generated=1
+
+Feb 23 14:47:01 ideapad2 wpa_supplicant[427]: wlp3s0f3u2: CTRL-EVENT-CONNECTED
+ - Connection to 90:55:de:__:__:__ completed [id=0 id_str=]
+Feb 23 14:47:04 ideapad2 wpa_supplicant[427]: wlp3s0f3u2: CTRL-EVENT-BEACON-LOSS
+Feb 23 14:47:05 ideapad2 wpa_supplicant[427]: wlp3s0f3u2: CTRL-EVENT-DISCONNECTED
+ bssid=90:55:de:__:__:__ reason=4 locally_generated=1
+
+This is caused by a mistake in the chip initialisation. This version of
+the chip requires loading an extra AGC table right after the main one,
+but the extra table is being loaded at the wrong time, in
+rtw_chip_board_info_setup().
+
+Move the extra AGC table loading to the right place, in
+rtw_phy_load_tables().
+
+The rtw_chip_board_info_setup() can only do "software" things, and
+rtw_phy_load_tables() can really do IO.
+
+Fixes: 5d6651fe8583 ("rtw88: 8821c: support RFE type2 wifi NIC")
+Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
+Acked-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/276c31d8-b9a8-4e54-a3ac-09b74657aff7@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/main.c | 2 --
+ drivers/net/wireless/realtek/rtw88/phy.c | 3 +++
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
+index 4c8164db4a9e4..81f3112923f1c 100644
+--- a/drivers/net/wireless/realtek/rtw88/main.c
++++ b/drivers/net/wireless/realtek/rtw88/main.c
+@@ -1989,8 +1989,6 @@ static int rtw_chip_board_info_setup(struct rtw_dev *rtwdev)
+ rtw_phy_setup_phy_cond(rtwdev, 0);
+
+ rtw_phy_init_tx_power(rtwdev);
+- if (rfe_def->agc_btg_tbl)
+- rtw_load_table(rtwdev, rfe_def->agc_btg_tbl);
+ rtw_load_table(rtwdev, rfe_def->phy_pg_tbl);
+ rtw_load_table(rtwdev, rfe_def->txpwr_lmt_tbl);
+ rtw_phy_tx_power_by_rate_config(hal);
+diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c
+index bd7d05e080848..fde7b532bc07e 100644
+--- a/drivers/net/wireless/realtek/rtw88/phy.c
++++ b/drivers/net/wireless/realtek/rtw88/phy.c
+@@ -1761,12 +1761,15 @@ static void rtw_load_rfk_table(struct rtw_dev *rtwdev)
+
+ void rtw_phy_load_tables(struct rtw_dev *rtwdev)
+ {
++ const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev);
+ const struct rtw_chip_info *chip = rtwdev->chip;
+ u8 rf_path;
+
+ rtw_load_table(rtwdev, chip->mac_tbl);
+ rtw_load_table(rtwdev, chip->bb_tbl);
+ rtw_load_table(rtwdev, chip->agc_tbl);
++ if (rfe_def->agc_btg_tbl)
++ rtw_load_table(rtwdev, rfe_def->agc_btg_tbl);
+ rtw_load_rfk_table(rtwdev);
+
+ for (rf_path = 0; rf_path < rtwdev->hal.rf_path_num; rf_path++) {
+--
+2.43.0
+
--- /dev/null
+From 3137d3cb8b21f73e82d1e30989f65057e291c12d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Mar 2024 00:35:58 +0200
+Subject: wifi: rtw88: 8821c: Fix false alarm count
+
+From: Bitterblue Smith <rtl8821cerfe2@gmail.com>
+
+[ Upstream commit c238adbc578eeb70cbc8fdd1bef3666b0f585b13 ]
+
+total_fa_cnt is supposed to include cck_fa_cnt and ofdm_fa_cnt, not just
+ofdm_fa_cnt.
+
+Fixes: 960361238b86 ("rtw88: 8821c: add false alarm statistics")
+Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
+Acked-by: Ping-Ke Shih <pkshih@realtek.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/f3cb6d17-e4e4-44a7-9c9b-72aed994b5c9@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/rtw8821c.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+index 609a2b86330d8..50e3e46f7d8aa 100644
+--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c
++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c
+@@ -674,9 +674,9 @@ static void rtw8821c_false_alarm_statistics(struct rtw_dev *rtwdev)
+
+ dm_info->cck_fa_cnt = cck_fa_cnt;
+ dm_info->ofdm_fa_cnt = ofdm_fa_cnt;
++ dm_info->total_fa_cnt = ofdm_fa_cnt;
+ if (cck_enable)
+ dm_info->total_fa_cnt += cck_fa_cnt;
+- dm_info->total_fa_cnt = ofdm_fa_cnt;
+
+ crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK);
+ dm_info->cck_ok_cnt = FIELD_GET(GENMASK(15, 0), crc32_cnt);
+--
+2.43.0
+
--- /dev/null
+From ea4840f8886aa4b1079c94acd93fc3bea0ec0c22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Feb 2024 17:42:13 +0100
+Subject: wifi: wfx: fix memory leak when starting AP
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jérôme Pouiller <jerome.pouiller@silabs.com>
+
+[ Upstream commit b8cfb7c819dd39965136a66fe3a7fde688d976fc ]
+
+Kmemleak reported this error:
+
+ unreferenced object 0xd73d1180 (size 184):
+ comm "wpa_supplicant", pid 1559, jiffies 13006305 (age 964.245s)
+ hex dump (first 32 bytes):
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00 00 00 00 00 00 00 00 1e 00 01 00 00 00 00 00 ................
+ backtrace:
+ [<5ca11420>] kmem_cache_alloc+0x20c/0x5ac
+ [<127bdd74>] __alloc_skb+0x144/0x170
+ [<fb8a5e38>] __netdev_alloc_skb+0x50/0x180
+ [<0f9fa1d5>] __ieee80211_beacon_get+0x290/0x4d4 [mac80211]
+ [<7accd02d>] ieee80211_beacon_get_tim+0x54/0x18c [mac80211]
+ [<41e25cc3>] wfx_start_ap+0xc8/0x234 [wfx]
+ [<93a70356>] ieee80211_start_ap+0x404/0x6b4 [mac80211]
+ [<a4a661cd>] nl80211_start_ap+0x76c/0x9e0 [cfg80211]
+ [<47bd8b68>] genl_rcv_msg+0x198/0x378
+ [<453ef796>] netlink_rcv_skb+0xd0/0x130
+ [<6b7c977a>] genl_rcv+0x34/0x44
+ [<66b2d04d>] netlink_unicast+0x1b4/0x258
+ [<f965b9b6>] netlink_sendmsg+0x1e8/0x428
+ [<aadb8231>] ____sys_sendmsg+0x1e0/0x274
+ [<d2b5212d>] ___sys_sendmsg+0x80/0xb4
+ [<69954f45>] __sys_sendmsg+0x64/0xa8
+ unreferenced object 0xce087000 (size 1024):
+ comm "wpa_supplicant", pid 1559, jiffies 13006305 (age 964.246s)
+ hex dump (first 32 bytes):
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 10 00 07 40 00 00 00 00 00 00 00 00 00 00 00 00 ...@............
+ backtrace:
+ [<9a993714>] __kmalloc_track_caller+0x230/0x600
+ [<f83ea192>] kmalloc_reserve.constprop.0+0x30/0x74
+ [<a2c61343>] __alloc_skb+0xa0/0x170
+ [<fb8a5e38>] __netdev_alloc_skb+0x50/0x180
+ [<0f9fa1d5>] __ieee80211_beacon_get+0x290/0x4d4 [mac80211]
+ [<7accd02d>] ieee80211_beacon_get_tim+0x54/0x18c [mac80211]
+ [<41e25cc3>] wfx_start_ap+0xc8/0x234 [wfx]
+ [<93a70356>] ieee80211_start_ap+0x404/0x6b4 [mac80211]
+ [<a4a661cd>] nl80211_start_ap+0x76c/0x9e0 [cfg80211]
+ [<47bd8b68>] genl_rcv_msg+0x198/0x378
+ [<453ef796>] netlink_rcv_skb+0xd0/0x130
+ [<6b7c977a>] genl_rcv+0x34/0x44
+ [<66b2d04d>] netlink_unicast+0x1b4/0x258
+ [<f965b9b6>] netlink_sendmsg+0x1e8/0x428
+ [<aadb8231>] ____sys_sendmsg+0x1e0/0x274
+ [<d2b5212d>] ___sys_sendmsg+0x80/0xb4
+
+However, since the kernel is build optimized, it seems the stack is not
+accurate. It appears the issue is related to wfx_set_mfp_ap(). The issue
+is obvious in this function: memory allocated by ieee80211_beacon_get()
+is never released. Fixing this leak makes kmemleak happy.
+
+Reported-by: Ulrich Mohr <u.mohr@semex-engcon.com>
+Co-developed-by: Ulrich Mohr <u.mohr@semex-engcon.com>
+Signed-off-by: Ulrich Mohr <u.mohr@semex-engcon.com>
+Fixes: 268bceec1684 ("staging: wfx: fix BA when device is AP and MFP is enabled")
+Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20240202164213.1606145-1-jerome.pouiller@silabs.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/silabs/wfx/sta.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/wireless/silabs/wfx/sta.c b/drivers/net/wireless/silabs/wfx/sta.c
+index 073e870b26415..871667650dbef 100644
+--- a/drivers/net/wireless/silabs/wfx/sta.c
++++ b/drivers/net/wireless/silabs/wfx/sta.c
+@@ -362,6 +362,7 @@ static int wfx_set_mfp_ap(struct wfx_vif *wvif)
+ const int pairwise_cipher_suite_count_offset = 8 / sizeof(u16);
+ const int pairwise_cipher_suite_size = 4 / sizeof(u16);
+ const int akm_suite_size = 4 / sizeof(u16);
++ int ret = -EINVAL;
+ const u16 *ptr;
+
+ if (unlikely(!skb))
+@@ -370,22 +371,26 @@ static int wfx_set_mfp_ap(struct wfx_vif *wvif)
+ ptr = (u16 *)cfg80211_find_ie(WLAN_EID_RSN, skb->data + ieoffset,
+ skb->len - ieoffset);
+ if (unlikely(!ptr))
+- return -EINVAL;
++ goto free_skb;
+
+ ptr += pairwise_cipher_suite_count_offset;
+ if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
+- return -EINVAL;
++ goto free_skb;
+
+ ptr += 1 + pairwise_cipher_suite_size * *ptr;
+ if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
+- return -EINVAL;
++ goto free_skb;
+
+ ptr += 1 + akm_suite_size * *ptr;
+ if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
+- return -EINVAL;
++ goto free_skb;
+
+ wfx_hif_set_mfp(wvif, *ptr & BIT(7), *ptr & BIT(6));
+- return 0;
++ ret = 0;
++
++free_skb:
++ dev_kfree_skb(skb);
++ return ret;
+ }
+
+ int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+--
+2.43.0
+
--- /dev/null
+From 0832dc3478b32a78df67368017a7c6ff2b4c6934 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jan 2024 15:56:32 +0100
+Subject: wifi: wilc1000: do not realloc workqueue everytime an interface is
+ added
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ajay Singh <ajay.kathat@microchip.com>
+
+[ Upstream commit 328efda22af81130c2ad981c110518cb29ff2f1d ]
+
+Commit 09ed8bfc5215 ("wilc1000: Rename workqueue from "WILC_wq" to
+"NETDEV-wq"") moved workqueue creation in wilc_netdev_ifc_init in order to
+set the interface name in the workqueue name. However, while the driver
+needs only one workqueue, the wilc_netdev_ifc_init is called each time we
+add an interface over a phy, which in turns overwrite the workqueue with a
+new one. This can be observed with the following commands:
+
+for i in $(seq 0 10)
+do
+ iw phy phy0 interface add wlan1 type managed
+ iw dev wlan1 del
+done
+ps -eo pid,comm|grep wlan
+
+ 39 kworker/R-wlan0
+ 98 kworker/R-wlan1
+102 kworker/R-wlan1
+105 kworker/R-wlan1
+108 kworker/R-wlan1
+111 kworker/R-wlan1
+114 kworker/R-wlan1
+117 kworker/R-wlan1
+120 kworker/R-wlan1
+123 kworker/R-wlan1
+126 kworker/R-wlan1
+129 kworker/R-wlan1
+
+Fix this leakage by putting back hif_workqueue allocation in
+wilc_cfg80211_init. Regarding the workqueue name, it is indeed relevant to
+set it lowercase, however it is not attached to a specific netdev, so
+enforcing netdev name in the name is not so relevant. Still, enrich the
+name with the wiphy name to make it clear which phy is using the workqueue.
+
+Fixes: 09ed8bfc5215 ("wilc1000: Rename workqueue from "WILC_wq" to "NETDEV-wq"")
+Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
+Co-developed-by: Alexis Lothoré <alexis.lothore@bootlin.com>
+Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20240115-wilc_1000_fixes-v1-3-54d29463a738@bootlin.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/microchip/wilc1000/cfg80211.c | 11 ++++++++++-
+ drivers/net/wireless/microchip/wilc1000/netdev.c | 10 +---------
+ 2 files changed, 11 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+index b545d93c6e374..2f75dc4b47975 100644
+--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c
++++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+@@ -1810,15 +1810,24 @@ int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
+ INIT_LIST_HEAD(&wl->rxq_head.list);
+ INIT_LIST_HEAD(&wl->vif_list);
+
++ wl->hif_workqueue = alloc_ordered_workqueue("%s", WQ_MEM_RECLAIM,
++ wiphy_name(wl->wiphy));
++ if (!wl->hif_workqueue) {
++ ret = -ENOMEM;
++ goto free_cfg;
++ }
+ vif = wilc_netdev_ifc_init(wl, "wlan%d", WILC_STATION_MODE,
+ NL80211_IFTYPE_STATION, false);
+ if (IS_ERR(vif)) {
+ ret = PTR_ERR(vif);
+- goto free_cfg;
++ goto free_hq;
+ }
+
+ return 0;
+
++free_hq:
++ destroy_workqueue(wl->hif_workqueue);
++
+ free_cfg:
+ wilc_wlan_cfg_deinit(wl);
+
+diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c
+index e9f59de31b0b9..0e6eeeed2e086 100644
+--- a/drivers/net/wireless/microchip/wilc1000/netdev.c
++++ b/drivers/net/wireless/microchip/wilc1000/netdev.c
+@@ -977,13 +977,6 @@ struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
+ goto error;
+ }
+
+- wl->hif_workqueue = alloc_ordered_workqueue("%s-wq", WQ_MEM_RECLAIM,
+- ndev->name);
+- if (!wl->hif_workqueue) {
+- ret = -ENOMEM;
+- goto unregister_netdev;
+- }
+-
+ ndev->needs_free_netdev = true;
+ vif->iftype = vif_type;
+ vif->idx = wilc_get_available_idx(wl);
+@@ -996,12 +989,11 @@ struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
+
+ return vif;
+
+-unregister_netdev:
++error:
+ if (rtnl_locked)
+ cfg80211_unregister_netdevice(ndev);
+ else
+ unregister_netdev(ndev);
+- error:
+ free_netdev(ndev);
+ return ERR_PTR(ret);
+ }
+--
+2.43.0
+
--- /dev/null
+From c1fb70e8be86dfa2891eae495b4e6f984e46e8f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jan 2024 08:57:32 +0100
+Subject: wifi: wilc1000: fix declarations ordering
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alexis Lothoré <alexis.lothore@bootlin.com>
+
+[ Upstream commit 535733e90e5d8912ebeccebb05b354a2d06ff459 ]
+
+Reorder parameters declaration in wilc_parse_join_bss_param to enforce
+reverse christmas tree
+
+Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20240105075733.36331-2-alexis.lothore@bootlin.com
+Stable-dep-of: 205c50306acf ("wifi: wilc1000: fix RCU usage in connect path")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/microchip/wilc1000/hif.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/microchip/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c
+index a1b75feec6edf..00ecf14afab01 100644
+--- a/drivers/net/wireless/microchip/wilc1000/hif.c
++++ b/drivers/net/wireless/microchip/wilc1000/hif.c
+@@ -374,13 +374,13 @@ static void handle_connect_timeout(struct work_struct *work)
+ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
+ struct cfg80211_crypto_settings *crypto)
+ {
+- struct wilc_join_bss_param *param;
+- struct ieee80211_p2p_noa_attr noa_attr;
+- u8 rates_len = 0;
++ const struct cfg80211_bss_ies *ies = rcu_dereference(bss->ies);
+ const u8 *tim_elm, *ssid_elm, *rates_ie, *supp_rates_ie;
+ const u8 *ht_ie, *wpa_ie, *wmm_ie, *rsn_ie;
++ struct ieee80211_p2p_noa_attr noa_attr;
++ struct wilc_join_bss_param *param;
++ u8 rates_len = 0;
+ int ret;
+- const struct cfg80211_bss_ies *ies = rcu_dereference(bss->ies);
+
+ param = kzalloc(sizeof(*param), GFP_KERNEL);
+ if (!param)
+--
+2.43.0
+
--- /dev/null
+From c18083195eba3ddecdbd744d1069f7a296ea8231 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jan 2024 15:56:34 +0100
+Subject: wifi: wilc1000: fix multi-vif management when deleting a vif
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ajay Singh <ajay.kathat@microchip.com>
+
+[ Upstream commit 12cfc9c8d3faf887a202c89bc312202445fca7e8 ]
+
+Adding then removing a second vif currently makes the first vif not working
+anymore. This is visible for example when we have a first interface
+connected to some access point:
+- create a wpa_supplicant.conf with some AP credentials
+- wpa_supplicant -Dnl80211 -c /etc/wpa_supplicant.conf -i wlan0
+- dhclient wlan0
+- iw phy phy0 interface add wlan1 type managed
+- iw dev wlan1 del
+wlan0 does not manage properly traffic anymore (eg: ping not working)
+
+This is due to vif mode being incorrectly reconfigured with some default
+values in del_virtual_intf, affecting by default first vif.
+
+Prevent first vif from being affected on second vif removal by removing vif
+mode change command in del_virtual_intf
+
+Fixes: 9bc061e88054 ("staging: wilc1000: added support to dynamically add/remove interfaces")
+Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
+Co-developed-by: Alexis Lothoré <alexis.lothore@bootlin.com>
+Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20240115-wilc_1000_fixes-v1-5-54d29463a738@bootlin.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/microchip/wilc1000/cfg80211.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+index 2f75dc4b47975..6f3245a43aef1 100644
+--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c
++++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+@@ -1615,7 +1615,6 @@ static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
+ cfg80211_unregister_netdevice(vif->ndev);
+ vif->monitor_flag = 0;
+
+- wilc_set_operation_mode(vif, 0, 0, 0);
+ mutex_lock(&wl->vif_mutex);
+ list_del_rcu(&vif->list);
+ wl->vif_num--;
+--
+2.43.0
+
--- /dev/null
+From 9e1e8289bbb2408c8f43f02e2cc68a11f0910e98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jan 2024 08:57:33 +0100
+Subject: wifi: wilc1000: fix RCU usage in connect path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alexis Lothoré <alexis.lothore@bootlin.com>
+
+[ Upstream commit 205c50306acf58a335eb19fa84e40140f4fe814f ]
+
+With lockdep enabled, calls to the connect function from cfg802.11 layer
+lead to the following warning:
+
+=============================
+WARNING: suspicious RCU usage
+6.7.0-rc1-wt+ #333 Not tainted
+-----------------------------
+drivers/net/wireless/microchip/wilc1000/hif.c:386
+suspicious rcu_dereference_check() usage!
+[...]
+stack backtrace:
+CPU: 0 PID: 100 Comm: wpa_supplicant Not tainted 6.7.0-rc1-wt+ #333
+Hardware name: Atmel SAMA5
+ unwind_backtrace from show_stack+0x18/0x1c
+ show_stack from dump_stack_lvl+0x34/0x48
+ dump_stack_lvl from wilc_parse_join_bss_param+0x7dc/0x7f4
+ wilc_parse_join_bss_param from connect+0x2c4/0x648
+ connect from cfg80211_connect+0x30c/0xb74
+ cfg80211_connect from nl80211_connect+0x860/0xa94
+ nl80211_connect from genl_rcv_msg+0x3fc/0x59c
+ genl_rcv_msg from netlink_rcv_skb+0xd0/0x1f8
+ netlink_rcv_skb from genl_rcv+0x2c/0x3c
+ genl_rcv from netlink_unicast+0x3b0/0x550
+ netlink_unicast from netlink_sendmsg+0x368/0x688
+ netlink_sendmsg from ____sys_sendmsg+0x190/0x430
+ ____sys_sendmsg from ___sys_sendmsg+0x110/0x158
+ ___sys_sendmsg from sys_sendmsg+0xe8/0x150
+ sys_sendmsg from ret_fast_syscall+0x0/0x1c
+
+This warning is emitted because in the connect path, when trying to parse
+target BSS parameters, we dereference a RCU pointer whithout being in RCU
+critical section.
+Fix RCU dereference usage by moving it to a RCU read critical section. To
+avoid wrapping the whole wilc_parse_join_bss_param under the critical
+section, just use the critical section to copy ies data
+
+Fixes: c460495ee072 ("staging: wilc1000: fix incorrent type in initializer")
+Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20240105075733.36331-3-alexis.lothore@bootlin.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/microchip/wilc1000/hif.c | 36 ++++++++++++-------
+ 1 file changed, 24 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/net/wireless/microchip/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c
+index 00ecf14afab01..5eb02902e875a 100644
+--- a/drivers/net/wireless/microchip/wilc1000/hif.c
++++ b/drivers/net/wireless/microchip/wilc1000/hif.c
+@@ -374,38 +374,49 @@ static void handle_connect_timeout(struct work_struct *work)
+ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
+ struct cfg80211_crypto_settings *crypto)
+ {
+- const struct cfg80211_bss_ies *ies = rcu_dereference(bss->ies);
+- const u8 *tim_elm, *ssid_elm, *rates_ie, *supp_rates_ie;
++ const u8 *ies_data, *tim_elm, *ssid_elm, *rates_ie, *supp_rates_ie;
+ const u8 *ht_ie, *wpa_ie, *wmm_ie, *rsn_ie;
+ struct ieee80211_p2p_noa_attr noa_attr;
++ const struct cfg80211_bss_ies *ies;
+ struct wilc_join_bss_param *param;
+- u8 rates_len = 0;
++ u8 rates_len = 0, ies_len;
+ int ret;
+
+ param = kzalloc(sizeof(*param), GFP_KERNEL);
+ if (!param)
+ return NULL;
+
++ rcu_read_lock();
++ ies = rcu_dereference(bss->ies);
++ ies_data = kmemdup(ies->data, ies->len, GFP_ATOMIC);
++ if (!ies_data) {
++ rcu_read_unlock();
++ kfree(param);
++ return NULL;
++ }
++ ies_len = ies->len;
++ rcu_read_unlock();
++
+ param->beacon_period = cpu_to_le16(bss->beacon_interval);
+ param->cap_info = cpu_to_le16(bss->capability);
+ param->bss_type = WILC_FW_BSS_TYPE_INFRA;
+ param->ch = ieee80211_frequency_to_channel(bss->channel->center_freq);
+ ether_addr_copy(param->bssid, bss->bssid);
+
+- ssid_elm = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
++ ssid_elm = cfg80211_find_ie(WLAN_EID_SSID, ies_data, ies_len);
+ if (ssid_elm) {
+ if (ssid_elm[1] <= IEEE80211_MAX_SSID_LEN)
+ memcpy(param->ssid, ssid_elm + 2, ssid_elm[1]);
+ }
+
+- tim_elm = cfg80211_find_ie(WLAN_EID_TIM, ies->data, ies->len);
++ tim_elm = cfg80211_find_ie(WLAN_EID_TIM, ies_data, ies_len);
+ if (tim_elm && tim_elm[1] >= 2)
+ param->dtim_period = tim_elm[3];
+
+ memset(param->p_suites, 0xFF, 3);
+ memset(param->akm_suites, 0xFF, 3);
+
+- rates_ie = cfg80211_find_ie(WLAN_EID_SUPP_RATES, ies->data, ies->len);
++ rates_ie = cfg80211_find_ie(WLAN_EID_SUPP_RATES, ies_data, ies_len);
+ if (rates_ie) {
+ rates_len = rates_ie[1];
+ if (rates_len > WILC_MAX_RATES_SUPPORTED)
+@@ -416,7 +427,7 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
+
+ if (rates_len < WILC_MAX_RATES_SUPPORTED) {
+ supp_rates_ie = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES,
+- ies->data, ies->len);
++ ies_data, ies_len);
+ if (supp_rates_ie) {
+ u8 ext_rates = supp_rates_ie[1];
+
+@@ -431,11 +442,11 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
+ }
+ }
+
+- ht_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies->data, ies->len);
++ ht_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies_data, ies_len);
+ if (ht_ie)
+ param->ht_capable = true;
+
+- ret = cfg80211_get_p2p_attr(ies->data, ies->len,
++ ret = cfg80211_get_p2p_attr(ies_data, ies_len,
+ IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
+ (u8 *)&noa_attr, sizeof(noa_attr));
+ if (ret > 0) {
+@@ -459,7 +470,7 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
+ }
+ wmm_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+ WLAN_OUI_TYPE_MICROSOFT_WMM,
+- ies->data, ies->len);
++ ies_data, ies_len);
+ if (wmm_ie) {
+ struct ieee80211_wmm_param_ie *ie;
+
+@@ -474,13 +485,13 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
+
+ wpa_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+ WLAN_OUI_TYPE_MICROSOFT_WPA,
+- ies->data, ies->len);
++ ies_data, ies_len);
+ if (wpa_ie) {
+ param->mode_802_11i = 1;
+ param->rsn_found = true;
+ }
+
+- rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies->data, ies->len);
++ rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies_data, ies_len);
+ if (rsn_ie) {
+ int rsn_ie_len = sizeof(struct element) + rsn_ie[1];
+ int offset = 8;
+@@ -514,6 +525,7 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
+ param->akm_suites[i] = crypto->akm_suites[i] & 0xFF;
+ }
+
++ kfree(ies_data);
+ return (void *)param;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 86d9828a3a7d608c9314108af03f145a76773892 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Feb 2024 13:57:37 +0100
+Subject: wifi: wilc1000: prevent use-after-free on vif when cleaning up all
+ interfaces
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alexis Lothoré <alexis.lothore@bootlin.com>
+
+[ Upstream commit cb5942b77c05d54310a0420cac12935e9b6aa21c ]
+
+wilc_netdev_cleanup currently triggers a KASAN warning, which can be
+observed on interface registration error path, or simply by
+removing the module/unbinding device from driver:
+
+echo spi0.1 > /sys/bus/spi/drivers/wilc1000_spi/unbind
+
+==================================================================
+BUG: KASAN: slab-use-after-free in wilc_netdev_cleanup+0x508/0x5cc
+Read of size 4 at addr c54d1ce8 by task sh/86
+
+CPU: 0 PID: 86 Comm: sh Not tainted 6.8.0-rc1+ #117
+Hardware name: Atmel SAMA5
+ unwind_backtrace from show_stack+0x18/0x1c
+ show_stack from dump_stack_lvl+0x34/0x58
+ dump_stack_lvl from print_report+0x154/0x500
+ print_report from kasan_report+0xac/0xd8
+ kasan_report from wilc_netdev_cleanup+0x508/0x5cc
+ wilc_netdev_cleanup from wilc_bus_remove+0xc8/0xec
+ wilc_bus_remove from spi_remove+0x8c/0xac
+ spi_remove from device_release_driver_internal+0x434/0x5f8
+ device_release_driver_internal from unbind_store+0xbc/0x108
+ unbind_store from kernfs_fop_write_iter+0x398/0x584
+ kernfs_fop_write_iter from vfs_write+0x728/0xf88
+ vfs_write from ksys_write+0x110/0x1e4
+ ksys_write from ret_fast_syscall+0x0/0x1c
+
+[...]
+
+Allocated by task 1:
+ kasan_save_track+0x30/0x5c
+ __kasan_kmalloc+0x8c/0x94
+ __kmalloc_node+0x1cc/0x3e4
+ kvmalloc_node+0x48/0x180
+ alloc_netdev_mqs+0x68/0x11dc
+ alloc_etherdev_mqs+0x28/0x34
+ wilc_netdev_ifc_init+0x34/0x8ec
+ wilc_cfg80211_init+0x690/0x910
+ wilc_bus_probe+0xe0/0x4a0
+ spi_probe+0x158/0x1b0
+ really_probe+0x270/0xdf4
+ __driver_probe_device+0x1dc/0x580
+ driver_probe_device+0x60/0x140
+ __driver_attach+0x228/0x5d4
+ bus_for_each_dev+0x13c/0x1a8
+ bus_add_driver+0x2a0/0x608
+ driver_register+0x24c/0x578
+ do_one_initcall+0x180/0x310
+ kernel_init_freeable+0x424/0x484
+ kernel_init+0x20/0x148
+ ret_from_fork+0x14/0x28
+
+Freed by task 86:
+ kasan_save_track+0x30/0x5c
+ kasan_save_free_info+0x38/0x58
+ __kasan_slab_free+0xe4/0x140
+ kfree+0xb0/0x238
+ device_release+0xc0/0x2a8
+ kobject_put+0x1d4/0x46c
+ netdev_run_todo+0x8fc/0x11d0
+ wilc_netdev_cleanup+0x1e4/0x5cc
+ wilc_bus_remove+0xc8/0xec
+ spi_remove+0x8c/0xac
+ device_release_driver_internal+0x434/0x5f8
+ unbind_store+0xbc/0x108
+ kernfs_fop_write_iter+0x398/0x584
+ vfs_write+0x728/0xf88
+ ksys_write+0x110/0x1e4
+ ret_fast_syscall+0x0/0x1c
+ [...]
+
+David Mosberger-Tan initial investigation [1] showed that this
+use-after-free is due to netdevice unregistration during vif list
+traversal. When unregistering a net device, since the needs_free_netdev has
+been set to true during registration, the netdevice object is also freed,
+and as a consequence, the corresponding vif object too, since it is
+attached to it as private netdevice data. The next occurrence of the loop
+then tries to access freed vif pointer to the list to move forward in the
+list.
+
+Fix this use-after-free thanks to two mechanisms:
+- navigate in the list with list_for_each_entry_safe, which allows to
+ safely modify the list as we go through each element. For each element,
+ remove it from the list with list_del_rcu
+- make sure to wait for RCU grace period end after each vif removal to make
+ sure it is safe to free the corresponding vif too (through
+ unregister_netdev)
+
+Since we are in a RCU "modifier" path (not a "reader" path), and because
+such path is expected not to be concurrent to any other modifier (we are
+using the vif_mutex lock), we do not need to use RCU list API, that's why
+we can benefit from list_for_each_entry_safe.
+
+[1] https://lore.kernel.org/linux-wireless/ab077dbe58b1ea5de0a3b2ca21f275a07af967d2.camel@egauge.net/
+
+Fixes: 8399918f3056 ("staging: wilc1000: use RCU list to maintain vif interfaces list")
+Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20240212-wilc_rework_deinit-v1-1-9203ae56c27f@bootlin.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/wireless/microchip/wilc1000/netdev.c | 28 +++++--------------
+ 1 file changed, 7 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c
+index 0e6eeeed2e086..b714da48eaa17 100644
+--- a/drivers/net/wireless/microchip/wilc1000/netdev.c
++++ b/drivers/net/wireless/microchip/wilc1000/netdev.c
+@@ -878,8 +878,7 @@ static const struct net_device_ops wilc_netdev_ops = {
+
+ void wilc_netdev_cleanup(struct wilc *wilc)
+ {
+- struct wilc_vif *vif;
+- int srcu_idx, ifc_cnt = 0;
++ struct wilc_vif *vif, *vif_tmp;
+
+ if (!wilc)
+ return;
+@@ -889,32 +888,19 @@ void wilc_netdev_cleanup(struct wilc *wilc)
+ wilc->firmware = NULL;
+ }
+
+- srcu_idx = srcu_read_lock(&wilc->srcu);
+- list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
++ list_for_each_entry_safe(vif, vif_tmp, &wilc->vif_list, list) {
++ mutex_lock(&wilc->vif_mutex);
++ list_del_rcu(&vif->list);
++ wilc->vif_num--;
++ mutex_unlock(&wilc->vif_mutex);
++ synchronize_srcu(&wilc->srcu);
+ if (vif->ndev)
+ unregister_netdev(vif->ndev);
+ }
+- srcu_read_unlock(&wilc->srcu, srcu_idx);
+
+ wilc_wfi_deinit_mon_interface(wilc, false);
+ destroy_workqueue(wilc->hif_workqueue);
+
+- while (ifc_cnt < WILC_NUM_CONCURRENT_IFC) {
+- mutex_lock(&wilc->vif_mutex);
+- if (wilc->vif_num <= 0) {
+- mutex_unlock(&wilc->vif_mutex);
+- break;
+- }
+- vif = wilc_get_wl_to_vif(wilc);
+- if (!IS_ERR(vif))
+- list_del_rcu(&vif->list);
+-
+- wilc->vif_num--;
+- mutex_unlock(&wilc->vif_mutex);
+- synchronize_srcu(&wilc->srcu);
+- ifc_cnt++;
+- }
+-
+ wilc_wlan_cfg_deinit(wilc);
+ wlan_deinit_locks(wilc);
+ wiphy_unregister(wilc->wiphy);
+--
+2.43.0
+
--- /dev/null
+From efc30bc90c477b665ec430a3e3128a247f5888a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Feb 2024 14:22:41 +0100
+Subject: wifi: wilc1000: revert reset line logic flip
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alexis Lothoré <alexis.lothore@bootlin.com>
+
+[ Upstream commit f3ec643947634bed41b97bd56b248f7c78498eab ]
+
+This reverts commit fcf690b0b47494df51d214db5c5a714a400b0257.
+
+When using a wilc1000 chip over a spi bus, users can optionally define a
+reset gpio and a chip enable gpio. The reset line of wilc1000 is active
+low, so to hold the chip in reset, a low (physical) value must be applied.
+
+The corresponding device tree binding documentation was introduced by
+commit f31ee3c0a555 ("wilc1000: Document enable-gpios and reset-gpios
+properties") and correctly indicates that the reset line is an active-low
+signal. The corresponding driver part, brought by commit ec031ac4792c
+("wilc1000: Add reset/enable GPIO support to SPI driver") was applying the
+correct logic. But commit fcf690b0b474 ("wifi: wilc1000: use correct
+sequence of RESET for chip Power-UP/Down") eventually flipped this logic
+and started misusing the gpiod APIs, applying an inverted logic when
+powering up/down the chip (for example, setting the reset line to a logic
+"1" during power up, which in fact asserts the reset line when device tree
+describes the reset line as GPIO_ACTIVE_LOW). As a consequence, any
+platform currently using the driver in SPI mode must use a faulty reset
+line description in device tree, or else chip will be maintained in reset
+and will not even allow to bring up the chip.
+
+Fix reset line usage by inverting back the gpiod APIs usage, setting the
+reset line to the logic value "0" when powering the chip, and the logic
+value "1" when powering off the chip.
+
+Fixes: fcf690b0b474 ("wifi: wilc1000: use correct sequence of RESET for chip Power-UP/Down")
+Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Acked-by: Ajay Singh <ajay.kathat@microchip.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20240217-wilc_1000_reset_line-v2-1-b216f433d7d5@bootlin.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/microchip/wilc1000/spi.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c
+index b0fc5e68feeca..5877e2c1fa0fc 100644
+--- a/drivers/net/wireless/microchip/wilc1000/spi.c
++++ b/drivers/net/wireless/microchip/wilc1000/spi.c
+@@ -191,11 +191,11 @@ static void wilc_wlan_power(struct wilc *wilc, bool on)
+ /* assert ENABLE: */
+ gpiod_set_value(gpios->enable, 1);
+ mdelay(5);
+- /* assert RESET: */
+- gpiod_set_value(gpios->reset, 1);
+- } else {
+ /* deassert RESET: */
+ gpiod_set_value(gpios->reset, 0);
++ } else {
++ /* assert RESET: */
++ gpiod_set_value(gpios->reset, 1);
+ /* deassert ENABLE: */
+ gpiod_set_value(gpios->enable, 0);
+ }
+--
+2.43.0
+
--- /dev/null
+From 12ff6d083e4dabb8aa536d4d936c695b143d3503 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Feb 2024 09:51:12 -0800
+Subject: x86, relocs: Ignore relocations in .notes section
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit aaa8736370db1a78f0e8434344a484f9fd20be3b ]
+
+When building with CONFIG_XEN_PV=y, .text symbols are emitted into
+the .notes section so that Xen can find the "startup_xen" entry point.
+This information is used prior to booting the kernel, so relocations
+are not useful. In fact, performing relocations against the .notes
+section means that the KASLR base is exposed since /sys/kernel/notes
+is world-readable.
+
+To avoid leaking the KASLR base without breaking unprivileged tools that
+are expecting to read /sys/kernel/notes, skip performing relocations in
+the .notes section. The values readable in .notes are then identical to
+those found in System.map.
+
+Reported-by: Guixiong Wei <guixiongwei@gmail.com>
+Closes: https://lore.kernel.org/all/20240218073501.54555-1-guixiongwei@gmail.com/
+Fixes: 5ead97c84fa7 ("xen: Core Xen implementation")
+Fixes: da1a679cde9b ("Add /sys/kernel/notes")
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/tools/relocs.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
+index 2925074b9a588..9a5b101c45023 100644
+--- a/arch/x86/tools/relocs.c
++++ b/arch/x86/tools/relocs.c
+@@ -653,6 +653,14 @@ static void print_absolute_relocs(void)
+ if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
+ continue;
+ }
++ /*
++ * Do not perform relocations in .notes section; any
++ * values there are meant for pre-boot consumption (e.g.
++ * startup_xen).
++ */
++ if (sec_applies->shdr.sh_type == SHT_NOTE) {
++ continue;
++ }
+ sh_symtab = sec_symtab->symtab;
+ sym_strtab = sec_symtab->link->strtab;
+ for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
+--
+2.43.0
+
--- /dev/null
+From bef7ed6b42556cc6da8be737daa2c8e46e906248 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jan 2024 10:08:07 -0800
+Subject: x86/resctrl: Implement new mba_MBps throttling heuristic
+
+From: Tony Luck <tony.luck@intel.com>
+
+[ Upstream commit c2427e70c1630d98966375fffc2b713ab9768a94 ]
+
+The mba_MBps feedback loop increases throttling when a group is using
+more bandwidth than the target set by the user in the schemata file, and
+decreases throttling when below target.
+
+To avoid possibly stepping throttling up and down on every poll a flag
+"delta_comp" is set whenever throttling is changed to indicate that the
+actual change in bandwidth should be recorded on the next poll in
+"delta_bw". Throttling is only reduced if the current bandwidth plus
+delta_bw is below the user target.
+
+This algorithm works well if the workload has steady bandwidth needs.
+But it can go badly wrong if the workload moves to a different phase
+just as the throttling level changed. E.g. if the workload becomes
+essentially idle right as throttling level is increased, the value
+calculated for delta_bw will be more or less the old bandwidth level.
+If the workload then resumes, Linux may never reduce throttling because
+current bandwidth plus delta_bw is above the target set by the user.
+
+Implement a simpler heuristic by assuming that in the worst case the
+currently measured bandwidth is being controlled by the current level of
+throttling. Compute how much it may increase if throttling is relaxed to
+the next higher level. If that is still below the user target, then it
+is ok to reduce the amount of throttling.
+
+Fixes: ba0f26d8529c ("x86/intel_rdt/mba_sc: Prepare for feedback loop")
+Reported-by: Xiaochen Shen <xiaochen.shen@intel.com>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
+Tested-by: Xiaochen Shen <xiaochen.shen@intel.com>
+Link: https://lore.kernel.org/r/20240122180807.70518-1-tony.luck@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/resctrl/internal.h | 4 ---
+ arch/x86/kernel/cpu/resctrl/monitor.c | 42 ++++++--------------------
+ 2 files changed, 10 insertions(+), 36 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h
+index 0b5c6c76f6f7b..4761d489a117a 100644
+--- a/arch/x86/kernel/cpu/resctrl/internal.h
++++ b/arch/x86/kernel/cpu/resctrl/internal.h
+@@ -281,14 +281,10 @@ struct rftype {
+ * struct mbm_state - status for each MBM counter in each domain
+ * @prev_bw_bytes: Previous bytes value read for bandwidth calculation
+ * @prev_bw: The most recent bandwidth in MBps
+- * @delta_bw: Difference between the current and previous bandwidth
+- * @delta_comp: Indicates whether to compute the delta_bw
+ */
+ struct mbm_state {
+ u64 prev_bw_bytes;
+ u32 prev_bw;
+- u32 delta_bw;
+- bool delta_comp;
+ };
+
+ /**
+diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c
+index 77538abeb72af..b9adb707750c6 100644
+--- a/arch/x86/kernel/cpu/resctrl/monitor.c
++++ b/arch/x86/kernel/cpu/resctrl/monitor.c
+@@ -428,9 +428,6 @@ static void mbm_bw_count(u32 rmid, struct rmid_read *rr)
+
+ cur_bw = bytes / SZ_1M;
+
+- if (m->delta_comp)
+- m->delta_bw = abs(cur_bw - m->prev_bw);
+- m->delta_comp = false;
+ m->prev_bw = cur_bw;
+ }
+
+@@ -508,11 +505,11 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
+ {
+ u32 closid, rmid, cur_msr_val, new_msr_val;
+ struct mbm_state *pmbm_data, *cmbm_data;
+- u32 cur_bw, delta_bw, user_bw;
+ struct rdt_resource *r_mba;
+ struct rdt_domain *dom_mba;
+ struct list_head *head;
+ struct rdtgroup *entry;
++ u32 cur_bw, user_bw;
+
+ if (!is_mbm_local_enabled())
+ return;
+@@ -531,7 +528,6 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
+
+ cur_bw = pmbm_data->prev_bw;
+ user_bw = dom_mba->mbps_val[closid];
+- delta_bw = pmbm_data->delta_bw;
+
+ /* MBA resource doesn't support CDP */
+ cur_msr_val = resctrl_arch_get_config(r_mba, dom_mba, closid, CDP_NONE);
+@@ -543,49 +539,31 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
+ list_for_each_entry(entry, head, mon.crdtgrp_list) {
+ cmbm_data = &dom_mbm->mbm_local[entry->mon.rmid];
+ cur_bw += cmbm_data->prev_bw;
+- delta_bw += cmbm_data->delta_bw;
+ }
+
+ /*
+ * Scale up/down the bandwidth linearly for the ctrl group. The
+ * bandwidth step is the bandwidth granularity specified by the
+ * hardware.
+- *
+- * The delta_bw is used when increasing the bandwidth so that we
+- * dont alternately increase and decrease the control values
+- * continuously.
+- *
+- * For ex: consider cur_bw = 90MBps, user_bw = 100MBps and if
+- * bandwidth step is 20MBps(> user_bw - cur_bw), we would keep
+- * switching between 90 and 110 continuously if we only check
+- * cur_bw < user_bw.
++ * Always increase throttling if current bandwidth is above the
++ * target set by user.
++ * But avoid thrashing up and down on every poll by checking
++ * whether a decrease in throttling is likely to push the group
++ * back over target. E.g. if currently throttling to 30% of bandwidth
++ * on a system with 10% granularity steps, check whether moving to
++ * 40% would go past the limit by multiplying current bandwidth by
++ * "(30 + 10) / 30".
+ */
+ if (cur_msr_val > r_mba->membw.min_bw && user_bw < cur_bw) {
+ new_msr_val = cur_msr_val - r_mba->membw.bw_gran;
+ } else if (cur_msr_val < MAX_MBA_BW &&
+- (user_bw > (cur_bw + delta_bw))) {
++ (user_bw > (cur_bw * (cur_msr_val + r_mba->membw.min_bw) / cur_msr_val))) {
+ new_msr_val = cur_msr_val + r_mba->membw.bw_gran;
+ } else {
+ return;
+ }
+
+ resctrl_arch_update_one(r_mba, dom_mba, closid, CDP_NONE, new_msr_val);
+-
+- /*
+- * Delta values are updated dynamically package wise for each
+- * rdtgrp every time the throttle MSR changes value.
+- *
+- * This is because (1)the increase in bandwidth is not perfectly
+- * linear and only "approximately" linear even when the hardware
+- * says it is linear.(2)Also since MBA is a core specific
+- * mechanism, the delta values vary based on number of cores used
+- * by the rdtgrp.
+- */
+- pmbm_data->delta_comp = true;
+- list_for_each_entry(entry, head, mon.crdtgrp_list) {
+- cmbm_data = &dom_mbm->mbm_local[entry->mon.rmid];
+- cmbm_data->delta_comp = true;
+- }
+ }
+
+ static void mbm_update(struct rdt_resource *r, struct rdt_domain *d, int rmid)
+--
+2.43.0
+
--- /dev/null
+From 9eb7c2dad9eff247d6fec8d3f2a3734224276ab3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Jan 2024 17:39:19 +0100
+Subject: x86/sme: Fix memory encryption setting if enabled by default and not
+ overridden
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+[ Upstream commit e814b59e6c2b11f5a3d007b2e61f7d550c354c3a ]
+
+Commit
+
+ cbebd68f59f0 ("x86/mm: Fix use of uninitialized buffer in sme_enable()")
+
+'fixed' an issue in sme_enable() detected by static analysis, and broke
+the common case in the process.
+
+cmdline_find_option() will return < 0 on an error, or when the command
+line argument does not appear at all. In this particular case, the
+latter is not an error condition, and so the early exit is wrong.
+
+Instead, without mem_encrypt= on the command line, the compile time
+default should be honoured, which could be to enable memory encryption,
+and this is currently broken.
+
+Fix it by setting sme_me_mask to a preliminary value based on the
+compile time default, and only omitting the command line argument test
+when cmdline_find_option() returns an error.
+
+ [ bp: Drop active_by_default while at it. ]
+
+Fixes: cbebd68f59f0 ("x86/mm: Fix use of uninitialized buffer in sme_enable()")
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Link: https://lore.kernel.org/r/20240126163918.2908990-2-ardb+git@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/mm/mem_encrypt_identity.c | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c
+index d94ebd8acdfde..a11a6ebbf5ecf 100644
+--- a/arch/x86/mm/mem_encrypt_identity.c
++++ b/arch/x86/mm/mem_encrypt_identity.c
+@@ -507,7 +507,6 @@ void __init sme_enable(struct boot_params *bp)
+ const char *cmdline_ptr, *cmdline_arg, *cmdline_on, *cmdline_off;
+ unsigned int eax, ebx, ecx, edx;
+ unsigned long feature_mask;
+- bool active_by_default;
+ unsigned long me_mask;
+ char buffer[16];
+ bool snp;
+@@ -593,22 +592,19 @@ void __init sme_enable(struct boot_params *bp)
+ : "p" (sme_cmdline_off));
+
+ if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT))
+- active_by_default = true;
+- else
+- active_by_default = false;
++ sme_me_mask = me_mask;
+
+ cmdline_ptr = (const char *)((u64)bp->hdr.cmd_line_ptr |
+ ((u64)bp->ext_cmd_line_ptr << 32));
+
+ if (cmdline_find_option(cmdline_ptr, cmdline_arg, buffer, sizeof(buffer)) < 0)
+- return;
++ goto out;
+
+ if (!strncmp(buffer, cmdline_on, sizeof(buffer)))
+ sme_me_mask = me_mask;
+ else if (!strncmp(buffer, cmdline_off, sizeof(buffer)))
+ sme_me_mask = 0;
+- else
+- sme_me_mask = active_by_default ? me_mask : 0;
++
+ out:
+ if (sme_me_mask) {
+ physical_mask &= ~sme_me_mask;
+--
+2.43.0
+