--- /dev/null
+From d1c110cf6709da18a41bbb316feedb105e93c4d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Apr 2023 08:42:00 +0200
+Subject: ACPI: video: Add backlight=native DMI quirk for Lenovo Ideapad Z470
+
+From: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+
+[ Upstream commit 96b709be183c56293933ef45b8b75f8af268c6de ]
+
+The Lenovo Ideapad Z470 predates Windows 8, so it defaults to using
+acpi_video for backlight control. But this is not functional on this
+model.
+
+Add a DMI quirk to use the native backlight interface which works.
+
+Link: https://bugzilla.suse.com/show_bug.cgi?id=1208724
+Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/video_detect.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
+index 707d6811615b8..073d26ddb6c21 100644
+--- a/drivers/acpi/video_detect.c
++++ b/drivers/acpi/video_detect.c
+@@ -443,6 +443,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
+ DMI_MATCH(DMI_BOARD_NAME, "Lenovo IdeaPad S405"),
+ },
+ },
++ {
++ /* https://bugzilla.suse.com/show_bug.cgi?id=1208724 */
++ .callback = video_detect_force_native,
++ /* Lenovo Ideapad Z470 */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Z470"),
++ },
++ },
+ {
+ /* https://bugzilla.redhat.com/show_bug.cgi?id=1187004 */
+ .callback = video_detect_force_native,
+--
+2.40.1
+
--- /dev/null
+From a59bdf9a4782db92fe710b5930ddb5ef3d6cf781 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Aug 2023 14:40:03 -0500
+Subject: ACPI: x86: s2idle: Catch multiple ACPI_TYPE_PACKAGE objects
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit 883cf0d4cf288313b71146ddebdf5d647b76c78b ]
+
+If a badly constructed firmware includes multiple `ACPI_TYPE_PACKAGE`
+objects while evaluating the AMD LPS0 _DSM, there will be a memory
+leak. Explicitly guard against this.
+
+Suggested-by: Bjorn Helgaas <helgaas@kernel.org>
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/x86/s2idle.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
+index ec84da6cc1bff..5510657d4be81 100644
+--- a/drivers/acpi/x86/s2idle.c
++++ b/drivers/acpi/x86/s2idle.c
+@@ -112,6 +112,12 @@ static void lpi_device_get_constraints_amd(void)
+ union acpi_object *package = &out_obj->package.elements[i];
+
+ if (package->type == ACPI_TYPE_PACKAGE) {
++ if (lpi_constraints_table) {
++ acpi_handle_err(lps0_device_handle,
++ "Duplicate constraints list\n");
++ goto free_acpi_buffer;
++ }
++
+ lpi_constraints_table = kcalloc(package->package.count,
+ sizeof(*lpi_constraints_table),
+ GFP_KERNEL);
+--
+2.40.1
+
--- /dev/null
+From 13093b2a0694dd186a0881ab682e12f57217019c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jun 2023 22:26:06 +0000
+Subject: ACPICA: Add AML_NO_OPERAND_RESOLVE flag to Timer
+
+From: Abhishek Mainkar <abmainkar@nvidia.com>
+
+[ Upstream commit 3a21ffdbc825e0919db9da0e27ee5ff2cc8a863e ]
+
+ACPICA commit 90310989a0790032f5a0140741ff09b545af4bc5
+
+According to the ACPI specification 19.6.134, no argument is required to be passed for ASL Timer instruction. For taking care of no argument, AML_NO_OPERAND_RESOLVE flag is added to ASL Timer instruction opcode.
+
+When ASL timer instruction interpreted by ACPI interpreter, getting error. After adding AML_NO_OPERAND_RESOLVE flag to ASL Timer instruction opcode, issue is not observed.
+
+=============================================================
+UBSAN: array-index-out-of-bounds in acpica/dswexec.c:401:12 index -1 is out of range for type 'union acpi_operand_object *[9]'
+CPU: 37 PID: 1678 Comm: cat Not tainted
+6.0.0-dev-th500-6.0.y-1+bcf8c46459e407-generic-64k
+HW name: NVIDIA BIOS v1.1.1-d7acbfc-dirty 12/19/2022 Call trace:
+ dump_backtrace+0xe0/0x130
+ show_stack+0x20/0x60
+ dump_stack_lvl+0x68/0x84
+ dump_stack+0x18/0x34
+ ubsan_epilogue+0x10/0x50
+ __ubsan_handle_out_of_bounds+0x80/0x90
+ acpi_ds_exec_end_op+0x1bc/0x6d8
+ acpi_ps_parse_loop+0x57c/0x618
+ acpi_ps_parse_aml+0x1e0/0x4b4
+ acpi_ps_execute_method+0x24c/0x2b8
+ acpi_ns_evaluate+0x3a8/0x4bc
+ acpi_evaluate_object+0x15c/0x37c
+ acpi_evaluate_integer+0x54/0x15c
+ show_power+0x8c/0x12c [acpi_power_meter]
+
+Link: https://github.com/acpica/acpica/commit/90310989
+Signed-off-by: Abhishek Mainkar <abmainkar@nvidia.com>
+Signed-off-by: Bob Moore <robert.moore@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/acpica/psopcode.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/acpica/psopcode.c b/drivers/acpi/acpica/psopcode.c
+index bef69e87a0a29..8c34c0ffb1d93 100644
+--- a/drivers/acpi/acpica/psopcode.c
++++ b/drivers/acpi/acpica/psopcode.c
+@@ -603,7 +603,7 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = {
+
+ /* 7E */ ACPI_OP("Timer", ARGP_TIMER_OP, ARGI_TIMER_OP, ACPI_TYPE_ANY,
+ AML_CLASS_EXECUTE, AML_TYPE_EXEC_0A_0T_1R,
+- AML_FLAGS_EXEC_0A_0T_1R),
++ AML_FLAGS_EXEC_0A_0T_1R | AML_NO_OPERAND_RESOLVE),
+
+ /* ACPI 5.0 opcodes */
+
+--
+2.40.1
+
--- /dev/null
+From fed5f4ce3c2da537cfb3f07ff6b6e3f4d3ae25ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Aug 2023 10:01:04 -0500
+Subject: ALSA: hda: intel-dsp-cfg: add LunarLake support
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit d2852b8c045ebd31d753b06f2810df5be30ed56a ]
+
+One more PCI ID for the road.
+
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Link: https://lore.kernel.org/r/20230802150105.24604-5-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/hda/intel-dsp-config.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c
+index 317bdf6dcbef4..2873420c9aca8 100644
+--- a/sound/hda/intel-dsp-config.c
++++ b/sound/hda/intel-dsp-config.c
+@@ -481,6 +481,14 @@ static const struct config_entry config_table[] = {
+ },
+ #endif
+
++/* Lunar Lake */
++#if IS_ENABLED(CONFIG_SND_SOC_SOF_LUNARLAKE)
++ /* Lunarlake-P */
++ {
++ .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
++ .device = PCI_DEVICE_ID_INTEL_HDA_LNL_P,
++ },
++#endif
+ };
+
+ static const struct config_entry *snd_intel_dsp_find_config
+--
+2.40.1
+
--- /dev/null
+From 2f34bbea482b499d3118f1f1ecb70d8bd5d12cc7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Aug 2023 09:32:18 +0800
+Subject: alx: fix OOB-read compiler warning
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: GONG, Ruiqi <gongruiqi1@huawei.com>
+
+[ Upstream commit 3a198c95c95da10ad844cbeade2fe40bdf14c411 ]
+
+The following message shows up when compiling with W=1:
+
+In function ‘fortify_memcpy_chk’,
+ inlined from ‘alx_get_ethtool_stats’ at drivers/net/ethernet/atheros/alx/ethtool.c:297:2:
+./include/linux/fortify-string.h:592:4: error: call to ‘__read_overflow2_field’
+declared with attribute warning: detected read beyond size of field (2nd parameter);
+maybe use struct_group()? [-Werror=attribute-warning]
+ 592 | __read_overflow2_field(q_size_field, size);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In order to get alx stats altogether, alx_get_ethtool_stats() reads
+beyond hw->stats.rx_ok. Fix this warning by directly copying hw->stats,
+and refactor the unnecessarily complicated BUILD_BUG_ON btw.
+
+Signed-off-by: GONG, Ruiqi <gongruiqi1@huawei.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20230821013218.1614265-1-gongruiqi@huaweicloud.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/atheros/alx/ethtool.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/atheros/alx/ethtool.c b/drivers/net/ethernet/atheros/alx/ethtool.c
+index b716adacd8159..7f6b69a523676 100644
+--- a/drivers/net/ethernet/atheros/alx/ethtool.c
++++ b/drivers/net/ethernet/atheros/alx/ethtool.c
+@@ -292,9 +292,8 @@ static void alx_get_ethtool_stats(struct net_device *netdev,
+ spin_lock(&alx->stats_lock);
+
+ alx_update_hw_stats(hw);
+- BUILD_BUG_ON(sizeof(hw->stats) - offsetof(struct alx_hw_stats, rx_ok) <
+- ALX_NUM_STATS * sizeof(u64));
+- memcpy(data, &hw->stats.rx_ok, ALX_NUM_STATS * sizeof(u64));
++ BUILD_BUG_ON(sizeof(hw->stats) != ALX_NUM_STATS * sizeof(u64));
++ memcpy(data, &hw->stats, sizeof(hw->stats));
+
+ spin_unlock(&alx->stats_lock);
+ }
+--
+2.40.1
+
--- /dev/null
+From 4090d1bf30dece5c330c4897d2e61dd824378693 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Aug 2023 09:37:32 +0100
+Subject: ARM: 9317/1: kexec: Make smp stop calls asynchronous
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mårten Lindahl <marten.lindahl@axis.com>
+
+[ Upstream commit 8922ba71c969d2a0c01a94372a71477d879470de ]
+
+If a panic is triggered by a hrtimer interrupt all online cpus will be
+notified and set offline. But as highlighted by commit 19dbdcb8039c
+("smp: Warn on function calls from softirq context") this call should
+not be made synchronous with disabled interrupts:
+
+ softdog: Initiating panic
+ Kernel panic - not syncing: Software Watchdog Timer expired
+ WARNING: CPU: 1 PID: 0 at kernel/smp.c:753 smp_call_function_many_cond
+ unwind_backtrace:
+ show_stack
+ dump_stack_lvl
+ __warn
+ warn_slowpath_fmt
+ smp_call_function_many_cond
+ smp_call_function
+ crash_smp_send_stop.part.0
+ machine_crash_shutdown
+ __crash_kexec
+ panic
+ softdog_fire
+ __hrtimer_run_queues
+ hrtimer_interrupt
+
+Make the smp call for machine_crash_nonpanic_core() asynchronous.
+
+Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/kernel/machine_kexec.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
+index f567032a09c0b..6d1938d1b4df7 100644
+--- a/arch/arm/kernel/machine_kexec.c
++++ b/arch/arm/kernel/machine_kexec.c
+@@ -92,16 +92,28 @@ void machine_crash_nonpanic_core(void *unused)
+ }
+ }
+
++static DEFINE_PER_CPU(call_single_data_t, cpu_stop_csd) =
++ CSD_INIT(machine_crash_nonpanic_core, NULL);
++
+ void crash_smp_send_stop(void)
+ {
+ static int cpus_stopped;
+ unsigned long msecs;
++ call_single_data_t *csd;
++ int cpu, this_cpu = raw_smp_processor_id();
+
+ if (cpus_stopped)
+ return;
+
+ atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
+- smp_call_function(machine_crash_nonpanic_core, NULL, false);
++ for_each_online_cpu(cpu) {
++ if (cpu == this_cpu)
++ continue;
++
++ csd = &per_cpu(cpu_stop_csd, cpu);
++ smp_call_function_single_async(cpu, csd);
++ }
++
+ msecs = 1000; /* Wait at most a second for the other cpus to stop */
+ while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
+ mdelay(1);
+--
+2.40.1
+
--- /dev/null
+From af99ecfba512af21a45b164986c67c779c448845 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Jun 2023 13:44:38 +0200
+Subject: arm64: dts: qcom: sm6125-pdx201: correct ramoops pmsg-size
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit c42f5452de6ad2599c6e5e2a64c180a4ac835d27 ]
+
+There is no 'msg-size' property in ramoops, so assume intention was for
+'pmsg-size':
+
+ sm6125-sony-xperia-seine-pdx201.dtb: ramoops@ffc00000: Unevaluated properties are not allowed ('msg-size' was unexpected)
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230618114442.140185-3-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/sm6125-sony-xperia-seine-pdx201.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
+index e1ab5b5189949..4a77b650c0d8d 100644
+--- a/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
++++ b/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
+@@ -73,7 +73,7 @@ pstore_mem: ramoops@ffc00000 {
+ reg = <0x0 0xffc40000 0x0 0xc0000>;
+ record-size = <0x1000>;
+ console-size = <0x40000>;
+- msg-size = <0x20000 0x20000>;
++ pmsg-size = <0x20000>;
+ };
+
+ cmdline_mem: memory@ffd00000 {
+--
+2.40.1
+
--- /dev/null
+From e85949aac1f21cd753dedd757d650c9d158be963 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Jun 2023 13:44:40 +0200
+Subject: arm64: dts: qcom: sm6350: correct ramoops pmsg-size
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit c86b97a72065e06eacb993dc71fa9febc93422af ]
+
+There is no 'msg-size' property in ramoops, so assume intention was for
+'pmsg-size':
+
+ sm6350-sony-xperia-lena-pdx213.dtb: ramoops@ffc00000: Unevaluated properties are not allowed ('msg-size' was unexpected)
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230618114442.140185-5-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/sm6350.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi
+index 34c8de4f43fba..cea7ca3f326fc 100644
+--- a/arch/arm64/boot/dts/qcom/sm6350.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi
+@@ -346,7 +346,7 @@ ramoops: ramoops@ffc00000 {
+ reg = <0 0xffc00000 0 0x100000>;
+ record-size = <0x1000>;
+ console-size = <0x40000>;
+- msg-size = <0x20000 0x20000>;
++ pmsg-size = <0x20000>;
+ ecc-size = <16>;
+ no-map;
+ };
+--
+2.40.1
+
--- /dev/null
+From c0f7b8185e4e6a606850e47ab95e44790726c076 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Jun 2023 13:44:41 +0200
+Subject: arm64: dts: qcom: sm8150-kumano: correct ramoops pmsg-size
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 4e6b942f092653ebcdbbc0819b2d1f08ab415bdc ]
+
+There is no 'msg-size' property in ramoops, so assume intention was for
+'pmsg-size':
+
+ sm8150-sony-xperia-kumano-griffin.dtb: ramoops@ffc00000: Unevaluated properties are not allowed ('msg-size' was unexpected)
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230618114442.140185-6-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-sony-xperia-kumano.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi b/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi
+index 04c71f74ab72d..c9aa7764fc59a 100644
+--- a/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi
+@@ -127,7 +127,7 @@ ramoops@ffc00000 {
+ reg = <0x0 0xffc00000 0x0 0x100000>;
+ record-size = <0x1000>;
+ console-size = <0x40000>;
+- msg-size = <0x20000 0x20000>;
++ pmsg-size = <0x20000>;
+ ecc-size = <16>;
+ no-map;
+ };
+--
+2.40.1
+
--- /dev/null
+From 46b926851c5b6bb8616dd2ae00ea92e5bf0c75f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Jun 2023 13:44:42 +0200
+Subject: arm64: dts: qcom: sm8250-edo: correct ramoops pmsg-size
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 7dc3606f91427414d00a2fb09e6e0e32c14c2093 ]
+
+There is no 'msg-size' property in ramoops, so assume intention was for
+'pmsg-size':
+
+ sm8250-sony-xperia-edo-pdx206.dtb: ramoops@ffc00000: Unevaluated properties are not allowed ('msg-size' was unexpected)
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20230618114442.140185-7-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/sm8250-sony-xperia-edo.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
+index 3b710c6a326a5..3b306dfb91e0d 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
+@@ -126,7 +126,7 @@ ramoops@ffc00000 {
+ reg = <0x0 0xffc00000 0x0 0x100000>;
+ record-size = <0x1000>;
+ console-size = <0x40000>;
+- msg-size = <0x20000 0x20000>;
++ pmsg-size = <0x20000>;
+ ecc-size = <16>;
+ no-map;
+ };
+--
+2.40.1
+
--- /dev/null
+From 1cf16de164ead5fe8e9ec0c6df57d1450daa2bbb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Jul 2023 16:42:38 -0500
+Subject: ASoC: Intel: sof_sdw: Update BT offload config for soundwire config
+
+From: Uday M Bhat <uday.m.bhat@intel.com>
+
+[ Upstream commit a14aded9299187bb17ef90700eb2cf1120ef5885 ]
+
+For soundwire config, SSP1 is used for BT offload. This is enabled
+in sof_sdw_quirk_table
+
+Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
+Signed-off-by: Uday M Bhat <uday.m.bhat@intel.com>
+Signed-off-by: Jairaj Arava <jairaj.arava@intel.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20230731214257.444605-5-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/intel/boards/sof_sdw.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
+index 064b6feb76167..414ac90273810 100644
+--- a/sound/soc/intel/boards/sof_sdw.c
++++ b/sound/soc/intel/boards/sof_sdw.c
+@@ -388,7 +388,9 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Google"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Rex"),
+ },
+- .driver_data = (void *)(SOF_SDW_PCH_DMIC),
++ .driver_data = (void *)(SOF_SDW_PCH_DMIC |
++ SOF_BT_OFFLOAD_SSP(1) |
++ SOF_SSP_BT_OFFLOAD_PRESENT),
+ },
+ /* LunarLake devices */
+ {
+--
+2.40.1
+
--- /dev/null
+From 3a28373f46c3bd85bfa40f29551d4d27ca602fc0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Jul 2023 16:37:43 -0500
+Subject: ASoC: SOF: topology: simplify code to prevent static analysis
+ warnings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+[ Upstream commit 55cb3dc271d81f1982c949a2ac483a6daf613b92 ]
+
+make KCFLAGS='-fanalyzer' sound/soc/sof/intel/ reports a possible NULL
+pointer dereference.
+
+sound/soc/sof/topology.c:1136:21: error: dereference of NULL ‘w’
+[CWE-476] [-Werror=analyzer-null-dereference]
+
+ 1136 | strcmp(w->sname, rtd->dai_link->stream_name))
+
+The code is rather confusing and can be simplified to make static
+analysis happy. No functionality change.
+
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Rander Wang <rander.wang@intel.com>
+Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
+Reviewed-by: Yaochun Hung <yc.hung@mediatek.com>
+Link: https://lore.kernel.org/r/20230731213748.440285-4-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/topology.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
+index 872e44408298f..e7305ce57ea1f 100644
+--- a/sound/soc/sof/topology.c
++++ b/sound/soc/sof/topology.c
+@@ -1086,16 +1086,17 @@ static void sof_disconnect_dai_widget(struct snd_soc_component *scomp,
+ {
+ struct snd_soc_card *card = scomp->card;
+ struct snd_soc_pcm_runtime *rtd;
++ const char *sname = w->sname;
+ struct snd_soc_dai *cpu_dai;
+ int i;
+
+- if (!w->sname)
++ if (!sname)
+ return;
+
+ list_for_each_entry(rtd, &card->rtd_list, list) {
+ /* does stream match DAI link ? */
+ if (!rtd->dai_link->stream_name ||
+- strcmp(w->sname, rtd->dai_link->stream_name))
++ strcmp(sname, rtd->dai_link->stream_name))
+ continue;
+
+ switch (w->id) {
+--
+2.40.1
+
--- /dev/null
+From 280ee4787a451c85158a519c9577a95f61aa3bd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 13:33:12 +0800
+Subject: autofs: fix memory leak of waitqueues in autofs_catatonic_mode
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit ccbe77f7e45dfb4420f7f531b650c00c6e9c7507 ]
+
+Syzkaller reports a memory leak:
+
+BUG: memory leak
+unreferenced object 0xffff88810b279e00 (size 96):
+ comm "syz-executor399", pid 3631, jiffies 4294964921 (age 23.870s)
+ hex dump (first 32 bytes):
+ 00 00 00 00 00 00 00 00 08 9e 27 0b 81 88 ff ff ..........'.....
+ 08 9e 27 0b 81 88 ff ff 00 00 00 00 00 00 00 00 ..'.............
+ backtrace:
+ [<ffffffff814cfc90>] kmalloc_trace+0x20/0x90 mm/slab_common.c:1046
+ [<ffffffff81bb75ca>] kmalloc include/linux/slab.h:576 [inline]
+ [<ffffffff81bb75ca>] autofs_wait+0x3fa/0x9a0 fs/autofs/waitq.c:378
+ [<ffffffff81bb88a7>] autofs_do_expire_multi+0xa7/0x3e0 fs/autofs/expire.c:593
+ [<ffffffff81bb8c33>] autofs_expire_multi+0x53/0x80 fs/autofs/expire.c:619
+ [<ffffffff81bb6972>] autofs_root_ioctl_unlocked+0x322/0x3b0 fs/autofs/root.c:897
+ [<ffffffff81bb6a95>] autofs_root_ioctl+0x25/0x30 fs/autofs/root.c:910
+ [<ffffffff81602a9c>] vfs_ioctl fs/ioctl.c:51 [inline]
+ [<ffffffff81602a9c>] __do_sys_ioctl fs/ioctl.c:870 [inline]
+ [<ffffffff81602a9c>] __se_sys_ioctl fs/ioctl.c:856 [inline]
+ [<ffffffff81602a9c>] __x64_sys_ioctl+0xfc/0x140 fs/ioctl.c:856
+ [<ffffffff84608225>] do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ [<ffffffff84608225>] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
+ [<ffffffff84800087>] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+autofs_wait_queue structs should be freed if their wait_ctr becomes zero.
+Otherwise they will be lost.
+
+In this case an AUTOFS_IOC_EXPIRE_MULTI ioctl is done, then a new
+waitqueue struct is allocated in autofs_wait(), its initial wait_ctr
+equals 2. After that wait_event_killable() is interrupted (it returns
+-ERESTARTSYS), so that 'wq->name.name == NULL' condition may be not
+satisfied. Actually, this condition can be satisfied when
+autofs_wait_release() or autofs_catatonic_mode() is called and, what is
+also important, wait_ctr is decremented in those places. Upon the exit of
+autofs_wait(), wait_ctr is decremented to 1. Then the unmounting process
+begins: kill_sb calls autofs_catatonic_mode(), which should have freed the
+waitqueues, but it only decrements its usage counter to zero which is not
+a correct behaviour.
+
+edit:imk
+This description is of course not correct. The umount performed as a result
+of an expire is a umount of a mount that has been automounted, it's not the
+autofs mount itself. They happen independently, usually after everything
+mounted within the autofs file system has been expired away. If everything
+hasn't been expired away the automount daemon can still exit leaving mounts
+in place. But expires done in both cases will result in a notification that
+calls autofs_wait_release() with a result status. The problem case is the
+summary execution of of the automount daemon. In this case any waiting
+processes won't be woken up until either they are terminated or the mount
+is umounted.
+end edit: imk
+
+So in catatonic mode we should free waitqueues which counter becomes zero.
+
+edit: imk
+Initially I was concerned that the calling of autofs_wait_release() and
+autofs_catatonic_mode() was not mutually exclusive but that can't be the
+case (obviously) because the queue entry (or entries) is removed from the
+list when either of these two functions are called. Consequently the wait
+entry will be freed by only one of these functions or by the woken process
+in autofs_wait() depending on the order of the calls.
+end edit: imk
+
+Reported-by: syzbot+5e53f70e69ff0c0a1c0c@syzkaller.appspotmail.com
+Suggested-by: Takeshi Misawa <jeliantsurux@gmail.com>
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
+Signed-off-by: Ian Kent <raven@themaw.net>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Andrei Vagin <avagin@gmail.com>
+Cc: autofs@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Message-Id: <169112719161.7590.6700123246297365841.stgit@donald.themaw.net>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/autofs/waitq.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/autofs/waitq.c b/fs/autofs/waitq.c
+index 54c1f8b8b0757..efdc76732faed 100644
+--- a/fs/autofs/waitq.c
++++ b/fs/autofs/waitq.c
+@@ -32,8 +32,9 @@ void autofs_catatonic_mode(struct autofs_sb_info *sbi)
+ wq->status = -ENOENT; /* Magic is gone - report failure */
+ kfree(wq->name.name - wq->offset);
+ wq->name.name = NULL;
+- wq->wait_ctr--;
+ wake_up_interruptible(&wq->queue);
++ if (!--wq->wait_ctr)
++ kfree(wq);
+ wq = nwq;
+ }
+ fput(sbi->pipe); /* Close the pipe */
+--
+2.40.1
+
--- /dev/null
+From 9a4a46f639a3ae91224c580618f2cd6a7637c078 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Feb 2023 16:06:12 +0100
+Subject: block: factor out a bvec_set_page helper
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit d58cdfae6a22e5079656c487aad669597a0635c8 ]
+
+Add a helper to initialize a bvec based of a page pointer. This will help
+removing various open code bvec initializations.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Link: https://lore.kernel.org/r/20230203150634.3199647-2-hch@lst.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: 1f0bbf28940c ("nvmet-tcp: pass iov_len instead of sg->length to bvec_set_page()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bio-integrity.c | 7 +------
+ block/bio.c | 12 ++----------
+ include/linux/bvec.h | 15 +++++++++++++++
+ 3 files changed, 18 insertions(+), 16 deletions(-)
+
+diff --git a/block/bio-integrity.c b/block/bio-integrity.c
+index 91ffee6fc8cb4..4533eb4916610 100644
+--- a/block/bio-integrity.c
++++ b/block/bio-integrity.c
+@@ -124,23 +124,18 @@ int bio_integrity_add_page(struct bio *bio, struct page *page,
+ unsigned int len, unsigned int offset)
+ {
+ struct bio_integrity_payload *bip = bio_integrity(bio);
+- struct bio_vec *iv;
+
+ if (bip->bip_vcnt >= bip->bip_max_vcnt) {
+ printk(KERN_ERR "%s: bip_vec full\n", __func__);
+ return 0;
+ }
+
+- iv = bip->bip_vec + bip->bip_vcnt;
+-
+ if (bip->bip_vcnt &&
+ bvec_gap_to_prev(&bdev_get_queue(bio->bi_bdev)->limits,
+ &bip->bip_vec[bip->bip_vcnt - 1], offset))
+ return 0;
+
+- iv->bv_page = page;
+- iv->bv_len = len;
+- iv->bv_offset = offset;
++ bvec_set_page(&bip->bip_vec[bip->bip_vcnt], page, len, offset);
+ bip->bip_vcnt++;
+
+ return len;
+diff --git a/block/bio.c b/block/bio.c
+index d5cd825d6efc0..9ec72a78f1149 100644
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -976,10 +976,7 @@ int bio_add_hw_page(struct request_queue *q, struct bio *bio,
+ if (bio->bi_vcnt >= queue_max_segments(q))
+ return 0;
+
+- bvec = &bio->bi_io_vec[bio->bi_vcnt];
+- bvec->bv_page = page;
+- bvec->bv_len = len;
+- bvec->bv_offset = offset;
++ bvec_set_page(&bio->bi_io_vec[bio->bi_vcnt], page, len, offset);
+ bio->bi_vcnt++;
+ bio->bi_iter.bi_size += len;
+ return len;
+@@ -1055,15 +1052,10 @@ EXPORT_SYMBOL_GPL(bio_add_zone_append_page);
+ void __bio_add_page(struct bio *bio, struct page *page,
+ unsigned int len, unsigned int off)
+ {
+- struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt];
+-
+ WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED));
+ WARN_ON_ONCE(bio_full(bio, len));
+
+- bv->bv_page = page;
+- bv->bv_offset = off;
+- bv->bv_len = len;
+-
++ bvec_set_page(&bio->bi_io_vec[bio->bi_vcnt], page, len, off);
+ bio->bi_iter.bi_size += len;
+ bio->bi_vcnt++;
+ }
+diff --git a/include/linux/bvec.h b/include/linux/bvec.h
+index 35c25dff651a5..9e3dac51eb26b 100644
+--- a/include/linux/bvec.h
++++ b/include/linux/bvec.h
+@@ -35,6 +35,21 @@ struct bio_vec {
+ unsigned int bv_offset;
+ };
+
++/**
++ * bvec_set_page - initialize a bvec based off a struct page
++ * @bv: bvec to initialize
++ * @page: page the bvec should point to
++ * @len: length of the bvec
++ * @offset: offset into the page
++ */
++static inline void bvec_set_page(struct bio_vec *bv, struct page *page,
++ unsigned int len, unsigned int offset)
++{
++ bv->bv_page = page;
++ bv->bv_len = len;
++ bv->bv_offset = offset;
++}
++
+ struct bvec_iter {
+ sector_t bi_sector; /* device address in 512 byte
+ sectors */
+--
+2.40.1
+
--- /dev/null
+From b9cbcb26e426ef7b66b372237b0a3ba9e4aefce4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Jul 2023 21:06:47 +0000
+Subject: Bluetooth: Fix hci_suspend_sync crash
+
+From: Ying Hsu <yinghsu@chromium.org>
+
+[ Upstream commit 573ebae162111063eedc6c838a659ba628f66a0f ]
+
+If hci_unregister_dev() frees the hci_dev object but hci_suspend_notifier
+may still be accessing it, it can cause the program to crash.
+Here's the call trace:
+ <4>[102152.653246] Call Trace:
+ <4>[102152.653254] hci_suspend_sync+0x109/0x301 [bluetooth]
+ <4>[102152.653259] hci_suspend_dev+0x78/0xcd [bluetooth]
+ <4>[102152.653263] hci_suspend_notifier+0x42/0x7a [bluetooth]
+ <4>[102152.653268] notifier_call_chain+0x43/0x6b
+ <4>[102152.653271] __blocking_notifier_call_chain+0x48/0x69
+ <4>[102152.653273] __pm_notifier_call_chain+0x22/0x39
+ <4>[102152.653276] pm_suspend+0x287/0x57c
+ <4>[102152.653278] state_store+0xae/0xe5
+ <4>[102152.653281] kernfs_fop_write+0x109/0x173
+ <4>[102152.653284] __vfs_write+0x16f/0x1a2
+ <4>[102152.653287] ? selinux_file_permission+0xca/0x16f
+ <4>[102152.653289] ? security_file_permission+0x36/0x109
+ <4>[102152.653291] vfs_write+0x114/0x21d
+ <4>[102152.653293] __x64_sys_write+0x7b/0xdb
+ <4>[102152.653296] do_syscall_64+0x59/0x194
+ <4>[102152.653299] entry_SYSCALL_64_after_hwframe+0x5c/0xc1
+
+This patch holds the reference count of the hci_dev object while
+processing it in hci_suspend_notifier to avoid potential crash
+caused by the race condition.
+
+Signed-off-by: Ying Hsu <yinghsu@chromium.org>
+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 | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 146553c0054f6..fa4dd5fab0d44 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -2436,6 +2436,9 @@ static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action,
+ if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
+ return NOTIFY_DONE;
+
++ /* To avoid a potential race with hci_unregister_dev. */
++ hci_dev_hold(hdev);
++
+ if (action == PM_SUSPEND_PREPARE)
+ ret = hci_suspend_dev(hdev);
+ else if (action == PM_POST_SUSPEND)
+@@ -2445,6 +2448,7 @@ static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action,
+ bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d",
+ action, ret);
+
++ hci_dev_put(hdev);
+ return NOTIFY_DONE;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 76b09bbb2521d43fc62d5e2818e39ccdc8cc4e36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Jul 2023 19:16:32 +0800
+Subject: btrfs: add a helper to read the superblock metadata_uuid
+
+From: Anand Jain <anand.jain@oracle.com>
+
+[ Upstream commit 4844c3664a72d36cc79752cb651c78860b14c240 ]
+
+In some cases, we need to read the FSID from the superblock when the
+metadata_uuid is not set, and otherwise, read the metadata_uuid. So,
+add a helper.
+
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Tested-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
+Signed-off-by: Anand Jain <anand.jain@oracle.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: 6bfe3959b0e7 ("btrfs: compare the correct fsid/metadata_uuid in btrfs_validate_super")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/volumes.c | 8 ++++++++
+ fs/btrfs/volumes.h | 1 +
+ 2 files changed, 9 insertions(+)
+
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index 567c5c010f931..a40ebd2321d01 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -663,6 +663,14 @@ static int btrfs_open_one_device(struct btrfs_fs_devices *fs_devices,
+ return -EINVAL;
+ }
+
++u8 *btrfs_sb_fsid_ptr(struct btrfs_super_block *sb)
++{
++ bool has_metadata_uuid = (btrfs_super_incompat_flags(sb) &
++ BTRFS_FEATURE_INCOMPAT_METADATA_UUID);
++
++ return has_metadata_uuid ? sb->metadata_uuid : sb->fsid;
++}
++
+ /*
+ * Handle scanned device having its CHANGING_FSID_V2 flag set and the fs_devices
+ * being created with a disk that has already completed its fsid change. Such
+diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
+index 099def5613b87..ec2260177038e 100644
+--- a/fs/btrfs/volumes.h
++++ b/fs/btrfs/volumes.h
+@@ -757,5 +757,6 @@ int btrfs_verify_dev_extents(struct btrfs_fs_info *fs_info);
+ bool btrfs_repair_one_zone(struct btrfs_fs_info *fs_info, u64 logical);
+
+ bool btrfs_pinned_by_swapfile(struct btrfs_fs_info *fs_info, void *ptr);
++u8 *btrfs_sb_fsid_ptr(struct btrfs_super_block *sb);
+
+ #endif
+--
+2.40.1
+
--- /dev/null
+From dfdd51f45735d430d4275144adfe2f5d8601f96c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Jul 2023 19:16:35 +0800
+Subject: btrfs: compare the correct fsid/metadata_uuid in btrfs_validate_super
+
+From: Anand Jain <anand.jain@oracle.com>
+
+[ Upstream commit 6bfe3959b0e7a526f5c64747801a8613f002f05a ]
+
+The function btrfs_validate_super() should verify the metadata_uuid in
+the provided superblock argument. Because, all its callers expect it to
+do that.
+
+Such as in the following stacks:
+
+ write_all_supers()
+ sb = fs_info->super_for_commit;
+ btrfs_validate_write_super(.., sb)
+ btrfs_validate_super(.., sb, ..)
+
+ scrub_one_super()
+ btrfs_validate_super(.., sb, ..)
+
+And
+ check_dev_super()
+ btrfs_validate_super(.., sb, ..)
+
+However, it currently verifies the fs_info::super_copy::metadata_uuid
+instead. Fix this using the correct metadata_uuid in the superblock
+argument.
+
+CC: stable@vger.kernel.org # 5.4+
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Tested-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
+Signed-off-by: Anand Jain <anand.jain@oracle.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/disk-io.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index 64daae693afd1..c44f1fcc19097 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -2728,13 +2728,11 @@ int btrfs_validate_super(struct btrfs_fs_info *fs_info,
+ ret = -EINVAL;
+ }
+
+- if (btrfs_fs_incompat(fs_info, METADATA_UUID) &&
+- memcmp(fs_info->fs_devices->metadata_uuid,
+- fs_info->super_copy->metadata_uuid, BTRFS_FSID_SIZE)) {
++ if (memcmp(fs_info->fs_devices->metadata_uuid, btrfs_sb_fsid_ptr(sb),
++ BTRFS_FSID_SIZE) != 0) {
+ btrfs_err(fs_info,
+ "superblock metadata_uuid doesn't match metadata uuid of fs_devices: %pU != %pU",
+- fs_info->super_copy->metadata_uuid,
+- fs_info->fs_devices->metadata_uuid);
++ btrfs_sb_fsid_ptr(sb), fs_info->fs_devices->metadata_uuid);
+ ret = -EINVAL;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From a52a2d993e0bdc89fa8f8b76dd999b1615334e2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Aug 2023 19:02:28 +0800
+Subject: btrfs: output extra debug info if we failed to find an inline backref
+
+From: Qu Wenruo <wqu@suse.com>
+
+[ Upstream commit 7f72f50547b7af4ddf985b07fc56600a4deba281 ]
+
+[BUG]
+Syzbot reported several warning triggered inside
+lookup_inline_extent_backref().
+
+[CAUSE]
+As usual, the reproducer doesn't reliably trigger locally here, but at
+least we know the WARN_ON() is triggered when an inline backref can not
+be found, and it can only be triggered when @insert is true. (I.e.
+inserting a new inline backref, which means the backref should already
+exist)
+
+[ENHANCEMENT]
+After the WARN_ON(), dump all the parameters and the extent tree
+leaf to help debug.
+
+Link: https://syzkaller.appspot.com/bug?extid=d6f9ff86c1d804ba2bc6
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/extent-tree.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
+index 0640ef59fe660..08ff10a81cb90 100644
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -863,6 +863,11 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
+ err = -ENOENT;
+ goto out;
+ } else if (WARN_ON(ret)) {
++ btrfs_print_leaf(path->nodes[0]);
++ btrfs_err(fs_info,
++"extent item not found for insert, bytenr %llu num_bytes %llu parent %llu root_objectid %llu owner %llu offset %llu",
++ bytenr, num_bytes, parent, root_objectid, owner,
++ offset);
+ err = -EIO;
+ goto out;
+ }
+--
+2.40.1
+
--- /dev/null
+From de576c876f0f1a56c59c8b7124ce65d06c424158 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 13:38:01 +0300
+Subject: bus: ti-sysc: Configure uart quirks for k3 SoC
+
+From: Tony Lindgren <tony@atomide.com>
+
+[ Upstream commit 03a711d3cb83692733f865312f49e665c49de6de ]
+
+Enable the uart quirks similar to the earlier SoCs. Let's assume we are
+likely going to need a k3 specific quirk mask separate from the earlier
+SoCs, so let's not start changing the revision register mask at this point.
+
+Note that SYSC_QUIRK_LEGACY_IDLE will be needed until we can remove the
+need for pm_runtime_irq_safe() from 8250_omap driver.
+
+Reviewed-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/ti-sysc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
+index ac36b01cf6d5d..ddde1427c90c7 100644
+--- a/drivers/bus/ti-sysc.c
++++ b/drivers/bus/ti-sysc.c
+@@ -1548,6 +1548,8 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
+ SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE),
+ SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff,
+ SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE),
++ SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47424e03, 0xffffffff,
++ SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE),
+
+ /* Quirks that need to be set based on the module address */
+ SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -ENODEV, 0x50000800, 0xffffffff,
+--
+2.40.1
+
--- /dev/null
+From 1cfc5f74ded9f08df859f3408b717b117e91bab2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Jul 2023 08:15:52 +1000
+Subject: can: sun4i_can: Add acceptance register quirk
+
+From: John Watts <contact@jookia.org>
+
+[ Upstream commit 8cda0c6dfd42ee6f2586e7dffb553aaf1fcb62ca ]
+
+The Allwinner D1's CAN controllers have the ACPC and ACPM registers
+moved down. Compensate for this by adding an offset quirk for the
+acceptance registers.
+
+Signed-off-by: John Watts <contact@jookia.org>
+Link: https://lore.kernel.org/all/20230721221552.1973203-5-contact@jookia.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/sun4i_can.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
+index 2b78f9197681b..dd0c6cd76c5f5 100644
+--- a/drivers/net/can/sun4i_can.c
++++ b/drivers/net/can/sun4i_can.c
+@@ -205,9 +205,11 @@
+ * struct sun4ican_quirks - Differences between SoC variants.
+ *
+ * @has_reset: SoC needs reset deasserted.
++ * @acp_offset: Offset of ACPC and ACPM registers
+ */
+ struct sun4ican_quirks {
+ bool has_reset;
++ int acp_offset;
+ };
+
+ struct sun4ican_priv {
+@@ -216,6 +218,7 @@ struct sun4ican_priv {
+ struct clk *clk;
+ struct reset_control *reset;
+ spinlock_t cmdreg_lock; /* lock for concurrent cmd register writes */
++ int acp_offset;
+ };
+
+ static const struct can_bittiming_const sun4ican_bittiming_const = {
+@@ -338,8 +341,8 @@ static int sun4i_can_start(struct net_device *dev)
+ }
+
+ /* set filters - we accept all */
+- writel(0x00000000, priv->base + SUN4I_REG_ACPC_ADDR);
+- writel(0xFFFFFFFF, priv->base + SUN4I_REG_ACPM_ADDR);
++ writel(0x00000000, priv->base + SUN4I_REG_ACPC_ADDR + priv->acp_offset);
++ writel(0xFFFFFFFF, priv->base + SUN4I_REG_ACPM_ADDR + priv->acp_offset);
+
+ /* clear error counters and error code capture */
+ writel(0, priv->base + SUN4I_REG_ERRC_ADDR);
+@@ -768,10 +771,12 @@ static const struct ethtool_ops sun4ican_ethtool_ops = {
+
+ static const struct sun4ican_quirks sun4ican_quirks_a10 = {
+ .has_reset = false,
++ .acp_offset = 0,
+ };
+
+ static const struct sun4ican_quirks sun4ican_quirks_r40 = {
+ .has_reset = true,
++ .acp_offset = 0,
+ };
+
+ static const struct of_device_id sun4ican_of_match[] = {
+@@ -872,6 +877,7 @@ static int sun4ican_probe(struct platform_device *pdev)
+ priv->base = addr;
+ priv->clk = clk;
+ priv->reset = reset;
++ priv->acp_offset = quirks->acp_offset;
+ spin_lock_init(&priv->cmdreg_lock);
+
+ platform_set_drvdata(pdev, dev);
+--
+2.40.1
+
--- /dev/null
+From cd4c90fb76498e732ef3e24b05ca977745343770 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Jul 2023 08:15:53 +1000
+Subject: can: sun4i_can: Add support for the Allwinner D1
+
+From: John Watts <contact@jookia.org>
+
+[ Upstream commit 8abb95250ae6af2d51993da8fcae18da2ce24cc4 ]
+
+The controllers present in the D1 are extremely similar to the R40
+and require the same reset quirks, but An extra quirk is needed to support
+receiving packets.
+
+Signed-off-by: John Watts <contact@jookia.org>
+Link: https://lore.kernel.org/all/20230721221552.1973203-6-contact@jookia.org
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/Kconfig | 4 ++--
+ drivers/net/can/sun4i_can.c | 12 +++++++++++-
+ 2 files changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
+index 3048ad77edb35..8236aabebb394 100644
+--- a/drivers/net/can/Kconfig
++++ b/drivers/net/can/Kconfig
+@@ -174,10 +174,10 @@ config CAN_SLCAN
+
+ config CAN_SUN4I
+ tristate "Allwinner A10 CAN controller"
+- depends on MACH_SUN4I || MACH_SUN7I || COMPILE_TEST
++ depends on MACH_SUN4I || MACH_SUN7I || RISCV || COMPILE_TEST
+ help
+ Say Y here if you want to use CAN controller found on Allwinner
+- A10/A20 SoCs.
++ A10/A20/D1 SoCs.
+
+ To compile this driver as a module, choose M here: the module will
+ be called sun4i_can.
+diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
+index dd0c6cd76c5f5..c3a6b028ea4d6 100644
+--- a/drivers/net/can/sun4i_can.c
++++ b/drivers/net/can/sun4i_can.c
+@@ -91,6 +91,8 @@
+ #define SUN4I_REG_BUF12_ADDR 0x0070 /* CAN Tx/Rx Buffer 12 */
+ #define SUN4I_REG_ACPC_ADDR 0x0040 /* CAN Acceptance Code 0 */
+ #define SUN4I_REG_ACPM_ADDR 0x0044 /* CAN Acceptance Mask 0 */
++#define SUN4I_REG_ACPC_ADDR_D1 0x0028 /* CAN Acceptance Code 0 on the D1 */
++#define SUN4I_REG_ACPM_ADDR_D1 0x002C /* CAN Acceptance Mask 0 on the D1 */
+ #define SUN4I_REG_RBUF_RBACK_START_ADDR 0x0180 /* CAN transmit buffer start */
+ #define SUN4I_REG_RBUF_RBACK_END_ADDR 0x01b0 /* CAN transmit buffer end */
+
+@@ -779,6 +781,11 @@ static const struct sun4ican_quirks sun4ican_quirks_r40 = {
+ .acp_offset = 0,
+ };
+
++static const struct sun4ican_quirks sun4ican_quirks_d1 = {
++ .has_reset = true,
++ .acp_offset = (SUN4I_REG_ACPC_ADDR_D1 - SUN4I_REG_ACPC_ADDR),
++};
++
+ static const struct of_device_id sun4ican_of_match[] = {
+ {
+ .compatible = "allwinner,sun4i-a10-can",
+@@ -789,6 +796,9 @@ static const struct of_device_id sun4ican_of_match[] = {
+ }, {
+ .compatible = "allwinner,sun8i-r40-can",
+ .data = &sun4ican_quirks_r40
++ }, {
++ .compatible = "allwinner,sun20i-d1-can",
++ .data = &sun4ican_quirks_d1
+ }, {
+ /* sentinel */
+ },
+@@ -915,4 +925,4 @@ module_platform_driver(sun4i_can_driver);
+ MODULE_AUTHOR("Peter Chen <xingkongcp@gmail.com>");
+ MODULE_AUTHOR("Gerhard Bertelsmann <info@gerhard-bertelsmann.de>");
+ MODULE_LICENSE("Dual BSD/GPL");
+-MODULE_DESCRIPTION("CAN driver for Allwinner SoCs (A10/A20)");
++MODULE_DESCRIPTION("CAN driver for Allwinner SoCs (A10/A20/D1)");
+--
+2.40.1
+
--- /dev/null
+From a94392f8caf0405ba60e3d04494113c44246c5c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Aug 2023 09:32:18 +0000
+Subject: crypto: lib/mpi - avoid null pointer deref in mpi_cmp_ui()
+
+From: Mark O'Donovan <shiftee@posteo.net>
+
+[ Upstream commit 9e47a758b70167c9301d2b44d2569f86c7796f2d ]
+
+During NVMeTCP Authentication a controller can trigger a kernel
+oops by specifying the 8192 bit Diffie Hellman group and passing
+a correctly sized, but zeroed Diffie Hellamn value.
+mpi_cmp_ui() was detecting this if the second parameter was 0,
+but 1 is passed from dh_is_pubkey_valid(). This causes the null
+pointer u->d to be dereferenced towards the end of mpi_cmp_ui()
+
+Signed-off-by: Mark O'Donovan <shiftee@posteo.net>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/mpi/mpi-cmp.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/lib/mpi/mpi-cmp.c b/lib/mpi/mpi-cmp.c
+index c4cfa3ff05818..0835b6213235e 100644
+--- a/lib/mpi/mpi-cmp.c
++++ b/lib/mpi/mpi-cmp.c
+@@ -25,8 +25,12 @@ int mpi_cmp_ui(MPI u, unsigned long v)
+ mpi_limb_t limb = v;
+
+ mpi_normalize(u);
+- if (!u->nlimbs && !limb)
+- return 0;
++ if (u->nlimbs == 0) {
++ if (v == 0)
++ return 0;
++ else
++ return -1;
++ }
+ if (u->sign)
+ return -1;
+ if (u->nlimbs > 1)
+--
+2.40.1
+
--- /dev/null
+From 90ed4d11606f3c684987e55bc2f5c77d54b3e22e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Jun 2023 20:08:32 +0000
+Subject: crypto: lrw,xts - Replace strlcpy with strscpy
+
+From: Azeem Shaikh <azeemshaikh38@gmail.com>
+
+[ Upstream commit babb80b3ecc6f40c962e13c654ebcd27f25ee327 ]
+
+strlcpy() reads the entire source buffer first.
+This read may exceed the destination size limit.
+This is both inefficient and can lead to linear read
+overflows if a source string is not NUL-terminated [1].
+In an effort to remove strlcpy() completely [2], replace
+strlcpy() here with strscpy().
+
+Direct replacement is safe here since return value of -errno
+is used to check for truncation instead of sizeof(dest).
+
+[1] https://www.kernel.org/doc/html/latest/process/deprecated.html#strlcpy
+[2] https://github.com/KSPP/linux/issues/89
+
+Signed-off-by: Azeem Shaikh <azeemshaikh38@gmail.com>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/lrw.c | 6 +++---
+ crypto/xts.c | 6 +++---
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/crypto/lrw.c b/crypto/lrw.c
+index 8d59a66b65255..fb8892ed179f5 100644
+--- a/crypto/lrw.c
++++ b/crypto/lrw.c
+@@ -357,10 +357,10 @@ static int lrw_create(struct crypto_template *tmpl, struct rtattr **tb)
+ * cipher name.
+ */
+ if (!strncmp(cipher_name, "ecb(", 4)) {
+- unsigned len;
++ int len;
+
+- len = strlcpy(ecb_name, cipher_name + 4, sizeof(ecb_name));
+- if (len < 2 || len >= sizeof(ecb_name))
++ len = strscpy(ecb_name, cipher_name + 4, sizeof(ecb_name));
++ if (len < 2)
+ goto err_free_inst;
+
+ if (ecb_name[len - 1] != ')')
+diff --git a/crypto/xts.c b/crypto/xts.c
+index de6cbcf69bbd6..b05020657cdc8 100644
+--- a/crypto/xts.c
++++ b/crypto/xts.c
+@@ -396,10 +396,10 @@ static int xts_create(struct crypto_template *tmpl, struct rtattr **tb)
+ * cipher name.
+ */
+ if (!strncmp(cipher_name, "ecb(", 4)) {
+- unsigned len;
++ int len;
+
+- len = strlcpy(ctx->name, cipher_name + 4, sizeof(ctx->name));
+- if (len < 2 || len >= sizeof(ctx->name))
++ len = strscpy(ctx->name, cipher_name + 4, sizeof(ctx->name));
++ if (len < 2)
+ goto err_free_inst;
+
+ if (ctx->name[len - 1] != ')')
+--
+2.40.1
+
--- /dev/null
+From ac5d158eeae101317aec1228baace3c176dde535 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Jul 2023 11:44:19 +0200
+Subject: devlink: remove reload failed checks in params get/set callbacks
+
+From: Jiri Pirko <jiri@nvidia.com>
+
+[ Upstream commit 633d76ad01ad0321a1ace3e5cc4fed06753d7ac4 ]
+
+The checks in question were introduced by:
+commit 6b4db2e528f6 ("devlink: Fix use-after-free after a failed reload").
+That fixed an issue of reload with mlxsw driver.
+
+Back then, that was a valid fix, because there was a limitation
+in place that prevented drivers from registering/unregistering params
+when devlink instance was registered.
+
+It was possible to do the fix differently by changing drivers to
+register/unregister params in appropriate places making sure the ops
+operate only on memory which is allocated and initialized. But that,
+as a dependency, would require to remove the limitation mentioned above.
+
+Eventually, this limitation was lifted by:
+commit 1d18bb1a4ddd ("devlink: allow registering parameters after the instance")
+
+Also, the alternative fix (which also fixed another issue) was done by:
+commit 74cbc3c03c82 ("mlxsw: spectrum_acl_tcam: Move devlink param to TCAM code").
+
+Therefore, the checks are no longer relevant. Each driver should make
+sure to have the params registered only when the memory the ops
+are working with is allocated and initialized.
+
+So remove the checks.
+
+Signed-off-by: Jiri Pirko <jiri@nvidia.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/devlink/leftover.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/devlink/leftover.c b/net/devlink/leftover.c
+index 63188d6a50fe9..032c7af065cd9 100644
+--- a/net/devlink/leftover.c
++++ b/net/devlink/leftover.c
+@@ -5218,7 +5218,7 @@ static int devlink_param_get(struct devlink *devlink,
+ const struct devlink_param *param,
+ struct devlink_param_gset_ctx *ctx)
+ {
+- if (!param->get || devlink->reload_failed)
++ if (!param->get)
+ return -EOPNOTSUPP;
+ return param->get(devlink, param->id, ctx);
+ }
+@@ -5227,7 +5227,7 @@ static int devlink_param_set(struct devlink *devlink,
+ const struct devlink_param *param,
+ struct devlink_param_gset_ctx *ctx)
+ {
+- if (!param->set || devlink->reload_failed)
++ if (!param->set)
+ return -EOPNOTSUPP;
+ return param->set(devlink, param->id, ctx);
+ }
+--
+2.40.1
+
--- /dev/null
+From 91bb3600815a82d3dbc3aa23ae6a793f2595c40f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Oct 2022 20:22:10 +0300
+Subject: dma-buf: Add unlocked variant of attachment-mapping functions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+
+[ Upstream commit 19d6634d8789573a9212ce78dbb4348ffd4f7f78 ]
+
+Add unlocked variant of dma_buf_map/unmap_attachment() that will
+be used by drivers that don't take the reservation lock explicitly.
+
+Acked-by: Sumit Semwal <sumit.semwal@linaro.org>
+Acked-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20221017172229.42269-3-dmitry.osipenko@collabora.com
+Stable-dep-of: a2cb9cd6a394 ("misc: fastrpc: Fix incorrect DMA mapping unmap request")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma-buf/dma-buf.c | 53 +++++++++++++++++++++++++++++++++++++++
+ include/linux/dma-buf.h | 6 +++++
+ 2 files changed, 59 insertions(+)
+
+diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
+index eb6b59363c4f5..3d58514d04826 100644
+--- a/drivers/dma-buf/dma-buf.c
++++ b/drivers/dma-buf/dma-buf.c
+@@ -1105,6 +1105,34 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
+ }
+ EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment, DMA_BUF);
+
++/**
++ * dma_buf_map_attachment_unlocked - Returns the scatterlist table of the attachment;
++ * mapped into _device_ address space. Is a wrapper for map_dma_buf() of the
++ * dma_buf_ops.
++ * @attach: [in] attachment whose scatterlist is to be returned
++ * @direction: [in] direction of DMA transfer
++ *
++ * Unlocked variant of dma_buf_map_attachment().
++ */
++struct sg_table *
++dma_buf_map_attachment_unlocked(struct dma_buf_attachment *attach,
++ enum dma_data_direction direction)
++{
++ struct sg_table *sg_table;
++
++ might_sleep();
++
++ if (WARN_ON(!attach || !attach->dmabuf))
++ return ERR_PTR(-EINVAL);
++
++ dma_resv_lock(attach->dmabuf->resv, NULL);
++ sg_table = dma_buf_map_attachment(attach, direction);
++ dma_resv_unlock(attach->dmabuf->resv);
++
++ return sg_table;
++}
++EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment_unlocked, DMA_BUF);
++
+ /**
+ * dma_buf_unmap_attachment - unmaps and decreases usecount of the buffer;might
+ * deallocate the scatterlist associated. Is a wrapper for unmap_dma_buf() of
+@@ -1141,6 +1169,31 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
+ }
+ EXPORT_SYMBOL_NS_GPL(dma_buf_unmap_attachment, DMA_BUF);
+
++/**
++ * dma_buf_unmap_attachment_unlocked - unmaps and decreases usecount of the buffer;might
++ * deallocate the scatterlist associated. Is a wrapper for unmap_dma_buf() of
++ * dma_buf_ops.
++ * @attach: [in] attachment to unmap buffer from
++ * @sg_table: [in] scatterlist info of the buffer to unmap
++ * @direction: [in] direction of DMA transfer
++ *
++ * Unlocked variant of dma_buf_unmap_attachment().
++ */
++void dma_buf_unmap_attachment_unlocked(struct dma_buf_attachment *attach,
++ struct sg_table *sg_table,
++ enum dma_data_direction direction)
++{
++ might_sleep();
++
++ if (WARN_ON(!attach || !attach->dmabuf || !sg_table))
++ return;
++
++ dma_resv_lock(attach->dmabuf->resv, NULL);
++ dma_buf_unmap_attachment(attach, sg_table, direction);
++ dma_resv_unlock(attach->dmabuf->resv);
++}
++EXPORT_SYMBOL_NS_GPL(dma_buf_unmap_attachment_unlocked, DMA_BUF);
++
+ /**
+ * dma_buf_move_notify - notify attachments that DMA-buf is moving
+ *
+diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
+index 71731796c8c3a..9c31f1f430d8e 100644
+--- a/include/linux/dma-buf.h
++++ b/include/linux/dma-buf.h
+@@ -627,6 +627,12 @@ int dma_buf_begin_cpu_access(struct dma_buf *dma_buf,
+ enum dma_data_direction dir);
+ int dma_buf_end_cpu_access(struct dma_buf *dma_buf,
+ enum dma_data_direction dir);
++struct sg_table *
++dma_buf_map_attachment_unlocked(struct dma_buf_attachment *attach,
++ enum dma_data_direction direction);
++void dma_buf_unmap_attachment_unlocked(struct dma_buf_attachment *attach,
++ struct sg_table *sg_table,
++ enum dma_data_direction direction);
+
+ int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *,
+ unsigned long);
+--
+2.40.1
+
--- /dev/null
+From 9383f77b8de79fa3a3e12525927c6225d3c3937d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jul 2023 16:57:36 -0400
+Subject: drm/amd/display: Blocking invalid 420 modes on HDMI TMDS for DCN31
+
+From: Leo Chen <sancchen@amd.com>
+
+[ Upstream commit 026a71babf48efb6b9884a3a66fa31aec9e1ea54 ]
+
+[Why & How]
+HDMI TMDS does not have ODM support. Filtering 420 modes that
+exceed the 4096 FMT limitation on DCN31 will resolve
+intermittent corruptions issues.
+
+Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Acked-by: Tom Chung <chiahsuan.chung@amd.com>
+Signed-off-by: Leo Chen <sancchen@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
+index ebc04b72b284b..9c84561ff3bc4 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c
+@@ -4133,7 +4133,9 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ }
+ if (v->OutputFormat[k] == dm_420 && v->HActive[k] > DCN31_MAX_FMT_420_BUFFER_WIDTH
+ && v->ODMCombineEnablePerState[i][k] != dm_odm_combine_mode_4to1) {
+- if (v->HActive[k] / 2 > DCN31_MAX_FMT_420_BUFFER_WIDTH) {
++ if (v->Output[k] == dm_hdmi) {
++ FMTBufferExceeded = true;
++ } else if (v->HActive[k] / 2 > DCN31_MAX_FMT_420_BUFFER_WIDTH) {
+ v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1;
+ v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1;
+
+--
+2.40.1
+
--- /dev/null
+From 5bb9e0406bab19939d7fb1ea743e9aed61a55d7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jul 2023 22:44:13 -0400
+Subject: drm/amd/display: Blocking invalid 420 modes on HDMI TMDS for DCN314
+
+From: Leo Chen <sancchen@amd.com>
+
+[ Upstream commit 4c6107a653ccf361cb1b6ba35d558a1a5e6e57ac ]
+
+[Why & How]
+HDMI TMDS does not have ODM support. Filtering 420 modes that
+exceed the 4096 FMT limitation on DCN314 will resolve
+intermittent corruptions issues.
+
+Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Acked-by: Tom Chung <chiahsuan.chung@amd.com>
+Signed-off-by: Leo Chen <sancchen@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c
+index 4998b211ccac7..5b47ccde64241 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c
+@@ -4225,7 +4225,9 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
+ }
+ if (v->OutputFormat[k] == dm_420 && v->HActive[k] > DCN314_MAX_FMT_420_BUFFER_WIDTH
+ && v->ODMCombineEnablePerState[i][k] != dm_odm_combine_mode_4to1) {
+- if (v->HActive[k] / 2 > DCN314_MAX_FMT_420_BUFFER_WIDTH) {
++ if (v->Output[k] == dm_hdmi) {
++ FMTBufferExceeded = true;
++ } else if (v->HActive[k] / 2 > DCN314_MAX_FMT_420_BUFFER_WIDTH) {
+ v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1;
+ v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1;
+
+--
+2.40.1
+
--- /dev/null
+From c28d42afebaf7585598bb56c9d63e9e2f896e8aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 16:17:03 -0400
+Subject: drm/amd/display: Fix underflow issue on 175hz timing
+
+From: Leo Ma <hanghong.ma@amd.com>
+
+[ Upstream commit 735688eb905db529efea0c78466fccc1461c3fde ]
+
+[Why]
+Screen underflows happen on 175hz timing for 3 plane overlay case.
+
+[How]
+Based on dst y prefetch value clamp to equ or oto for bandwidth
+calculation.
+
+Reviewed-by: Dillon Varone <dillon.varone@amd.com>
+Acked-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Leo Ma <hanghong.ma@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../amd/display/dc/dml/dcn32/display_mode_vba_util_32.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
+index b53feeaf5cf11..23e4be2ad63f9 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
+@@ -3454,6 +3454,7 @@ bool dml32_CalculatePrefetchSchedule(
+ double TimeForFetchingMetaPTE = 0;
+ double TimeForFetchingRowInVBlank = 0;
+ double LinesToRequestPrefetchPixelData = 0;
++ double LinesForPrefetchBandwidth = 0;
+ unsigned int HostVMDynamicLevelsTrips;
+ double trip_to_mem;
+ double Tvm_trips;
+@@ -3883,11 +3884,15 @@ bool dml32_CalculatePrefetchSchedule(
+ TimeForFetchingMetaPTE = Tvm_oto;
+ TimeForFetchingRowInVBlank = Tr0_oto;
+ *PrefetchBandwidth = prefetch_bw_oto;
++ /* Clamp to oto for bandwidth calculation */
++ LinesForPrefetchBandwidth = dst_y_prefetch_oto;
+ } else {
+ *DestinationLinesForPrefetch = dst_y_prefetch_equ;
+ TimeForFetchingMetaPTE = Tvm_equ;
+ TimeForFetchingRowInVBlank = Tr0_equ;
+ *PrefetchBandwidth = prefetch_bw_equ;
++ /* Clamp to equ for bandwidth calculation */
++ LinesForPrefetchBandwidth = dst_y_prefetch_equ;
+ }
+
+ *DestinationLinesToRequestVMInVBlank = dml_ceil(4.0 * TimeForFetchingMetaPTE / LineTime, 1.0) / 4.0;
+@@ -3895,7 +3900,7 @@ bool dml32_CalculatePrefetchSchedule(
+ *DestinationLinesToRequestRowInVBlank =
+ dml_ceil(4.0 * TimeForFetchingRowInVBlank / LineTime, 1.0) / 4.0;
+
+- LinesToRequestPrefetchPixelData = *DestinationLinesForPrefetch -
++ LinesToRequestPrefetchPixelData = LinesForPrefetchBandwidth -
+ *DestinationLinesToRequestVMInVBlank - 2 * *DestinationLinesToRequestRowInVBlank;
+
+ #ifdef __DML_VBA_DEBUG__
+--
+2.40.1
+
--- /dev/null
+From e25be18d723966baba3a94195c702abead286d82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jul 2023 10:40:48 -0400
+Subject: drm/amd/display: Use DTBCLK as refclk instead of DPREFCLK
+
+From: Austin Zheng <austin.zheng@amd.com>
+
+[ Upstream commit 4a30cc2bd281fa176a68b5305cd3695d636152ad ]
+
+[Why]
+Flash of corruption observed when UCLK switching after transitioning
+from DTBCLK to DPREFCLK on subVP(DP) + subVP(HDMI) config
+Scenario where DPREFCLK is required instead of DTBCLK is not expected
+
+[How]
+Always set the DTBCLK source as DTBCLK0
+
+Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
+Acked-by: Tom Chung <chiahsuan.chung@amd.com>
+Signed-off-by: Austin Zheng <austin.zheng@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
+index ffbb739d85b69..8496ff4a25e35 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
+@@ -290,7 +290,8 @@ static void dccg32_set_dpstreamclk(
+ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+ /* set the dtbclk_p source */
+- dccg32_set_dtbclk_p_src(dccg, src, otg_inst);
++ /* always program refclk as DTBCLK. No use-case expected to require DPREFCLK as refclk */
++ dccg32_set_dtbclk_p_src(dccg, DTBCLK0, otg_inst);
+
+ /* enabled to select one of the DTBCLKs for pipe */
+ switch (dp_hpo_inst) {
+--
+2.40.1
+
--- /dev/null
+From 140859904fcda5b50191983cd3c3e50f60899c6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Jun 2023 22:19:00 +0200
+Subject: drm/bridge: tc358762: Instruct DSI host to generate HSE packets
+
+From: Marek Vasut <marex@denx.de>
+
+[ Upstream commit 362fa8f6e6a05089872809f4465bab9d011d05b3 ]
+
+This bridge seems to need the HSE packet, otherwise the image is
+shifted up and corrupted at the bottom. This makes the bridge
+work with Samsung DSIM on i.MX8MM and i.MX8MP.
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230615201902.566182-3-marex@denx.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/tc358762.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/tc358762.c b/drivers/gpu/drm/bridge/tc358762.c
+index 7f4fce1aa9988..8db981e7759b9 100644
+--- a/drivers/gpu/drm/bridge/tc358762.c
++++ b/drivers/gpu/drm/bridge/tc358762.c
+@@ -216,7 +216,7 @@ static int tc358762_probe(struct mipi_dsi_device *dsi)
+ dsi->lanes = 1;
+ dsi->format = MIPI_DSI_FMT_RGB888;
+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
+- MIPI_DSI_MODE_LPM;
++ MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_VIDEO_HSE;
+
+ ret = tc358762_parse_dt(ctx);
+ if (ret < 0)
+--
+2.40.1
+
--- /dev/null
+From 3f5b8cd8dc557801fc10b0be94303893434d29a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Jun 2023 23:19:03 -0700
+Subject: drm/edid: Add quirk for OSVR HDK 2.0
+
+From: Ralph Campbell <rcampbell@nvidia.com>
+
+[ Upstream commit 98d4cb705bc00afd4a9a71cc1e84f7111682639a ]
+
+The OSVR virtual reality headset HDK 2.0 uses a different EDID
+vendor and device identifier than the HDK 1.1 - 1.4 headsets.
+Add the HDK 2.0 vendor and device identifier to the quirks table so
+that window managers do not try to display the desktop screen on the
+headset display.
+
+Closes: https://gitlab.freedesktop.org/drm/misc/-/issues/30
+Signed-off-by: Ralph Campbell <rcampbell@nvidia.com>
+Tested-by: Ralph Campbell <rcampbell@nvidia.com>
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230621061903.3422648-1-rcampbell@nvidia.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_edid.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
+index 739e0d40cca61..5ed77e3361fd7 100644
+--- a/drivers/gpu/drm/drm_edid.c
++++ b/drivers/gpu/drm/drm_edid.c
+@@ -231,6 +231,7 @@ static const struct edid_quirk {
+
+ /* OSVR HDK and HDK2 VR Headsets */
+ EDID_QUIRK('S', 'V', 'R', 0x1019, EDID_QUIRK_NON_DESKTOP),
++ EDID_QUIRK('A', 'U', 'O', 0x1111, EDID_QUIRK_NON_DESKTOP),
+ };
+
+ /*
+--
+2.40.1
+
--- /dev/null
+From c3716eae819f3491fcd1138ae7b83b9b27f7c1dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jun 2023 10:19:06 +0800
+Subject: drm/exynos: fix a possible null-pointer dereference due to data race
+ in exynos_drm_crtc_atomic_disable()
+
+From: Tuo Li <islituo@gmail.com>
+
+[ Upstream commit 2e63972a2de14482d0eae1a03a73e379f1c3f44c ]
+
+The variable crtc->state->event is often protected by the lock
+crtc->dev->event_lock when is accessed. However, it is accessed as a
+condition of an if statement in exynos_drm_crtc_atomic_disable() without
+holding the lock:
+
+ if (crtc->state->event && !crtc->state->active)
+
+However, if crtc->state->event is changed to NULL by another thread right
+after the conditions of the if statement is checked to be true, a
+null-pointer dereference can occur in drm_crtc_send_vblank_event():
+
+ e->pipe = pipe;
+
+To fix this possible null-pointer dereference caused by data race, the
+spin lock coverage is extended to protect the if statement as well as the
+function call to drm_crtc_send_vblank_event().
+
+Reported-by: BassCheck <bass@buaa.edu.cn>
+Link: https://sites.google.com/view/basscheck/home
+Signed-off-by: Tuo Li <islituo@gmail.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Added relevant link.
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/exynos/exynos_drm_crtc.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+index 4153f302de7c4..d19e796c20613 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+@@ -39,13 +39,12 @@ static void exynos_drm_crtc_atomic_disable(struct drm_crtc *crtc,
+ if (exynos_crtc->ops->atomic_disable)
+ exynos_crtc->ops->atomic_disable(exynos_crtc);
+
++ spin_lock_irq(&crtc->dev->event_lock);
+ if (crtc->state->event && !crtc->state->active) {
+- spin_lock_irq(&crtc->dev->event_lock);
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+- spin_unlock_irq(&crtc->dev->event_lock);
+-
+ crtc->state->event = NULL;
+ }
++ spin_unlock_irq(&crtc->dev->event_lock);
+ }
+
+ static int exynos_crtc_atomic_check(struct drm_crtc *crtc,
+--
+2.40.1
+
--- /dev/null
+From cade8250700a9279b2e809c45b7717db3967a1bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Sep 2023 10:14:20 +0800
+Subject: drm: gm12u320: Fix the timeout usage for usb_bulk_msg()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 7583028d359db3cd0072badcc576b4f9455fd27a ]
+
+The timeout arg of usb_bulk_msg() is ms already, which has been converted
+to jiffies by msecs_to_jiffies() in usb_start_wait_urb(). So fix the usage
+by removing the redundant msecs_to_jiffies() in the macros.
+
+And as Hans suggested, also remove msecs_to_jiffies() for the IDLE_TIMEOUT
+macro to make it consistent here and so change IDLE_TIMEOUT to
+msecs_to_jiffies(IDLE_TIMEOUT) where it is used.
+
+Fixes: e4f86e437164 ("drm: Add Grain Media GM12U320 driver v2")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Suggested-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20230904021421.1663892-1-ruanjinjie@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tiny/gm12u320.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c
+index 7441d992a5d7a..8b0a9059d3fdd 100644
+--- a/drivers/gpu/drm/tiny/gm12u320.c
++++ b/drivers/gpu/drm/tiny/gm12u320.c
+@@ -69,10 +69,10 @@ MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)");
+ #define READ_STATUS_SIZE 13
+ #define MISC_VALUE_SIZE 4
+
+-#define CMD_TIMEOUT msecs_to_jiffies(200)
+-#define DATA_TIMEOUT msecs_to_jiffies(1000)
+-#define IDLE_TIMEOUT msecs_to_jiffies(2000)
+-#define FIRST_FRAME_TIMEOUT msecs_to_jiffies(2000)
++#define CMD_TIMEOUT 200
++#define DATA_TIMEOUT 1000
++#define IDLE_TIMEOUT 2000
++#define FIRST_FRAME_TIMEOUT 2000
+
+ #define MISC_REQ_GET_SET_ECO_A 0xff
+ #define MISC_REQ_GET_SET_ECO_B 0x35
+@@ -388,7 +388,7 @@ static void gm12u320_fb_update_work(struct work_struct *work)
+ * switches back to showing its logo.
+ */
+ queue_delayed_work(system_long_wq, &gm12u320->fb_update.work,
+- IDLE_TIMEOUT);
++ msecs_to_jiffies(IDLE_TIMEOUT));
+
+ return;
+ err:
+--
+2.40.1
+
--- /dev/null
+From b8510b843d43a480096e0d37f624b04d9358d4b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 09:32:26 +0200
+Subject: drm/mediatek: dp: Change logging to dev for mtk_dp_aux_transfer()
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit fd70e2019bfbcb0ed90c5e23839bf510ce6acf8f ]
+
+Change logging from drm_{err,info}() to dev_{err,info}() in functions
+mtk_dp_aux_transfer() and mtk_dp_aux_do_transfer(): this will be
+essential to avoid getting NULL pointer kernel panics if any kind
+of error happens during AUX transfers happening before the bridge
+is attached.
+
+This may potentially start happening in a later commit implementing
+aux-bus support, as AUX transfers will be triggered from the panel
+driver (for EDID) before the mtk-dp bridge gets attached, and it's
+done in preparation for the same.
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20230725073234.55892-4-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_dp.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
+index 4c249939a6c3b..395a190274cfb 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dp.c
++++ b/drivers/gpu/drm/mediatek/mtk_dp.c
+@@ -847,7 +847,7 @@ static int mtk_dp_aux_do_transfer(struct mtk_dp *mtk_dp, bool is_read, u8 cmd,
+ u32 phy_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3628) &
+ AUX_RX_PHY_STATE_AUX_TX_P0_MASK;
+ if (phy_status != AUX_RX_PHY_STATE_AUX_TX_P0_RX_IDLE) {
+- drm_err(mtk_dp->drm_dev,
++ dev_err(mtk_dp->dev,
+ "AUX Rx Aux hang, need SW reset\n");
+ return -EIO;
+ }
+@@ -2062,7 +2062,7 @@ static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
+ is_read = true;
+ break;
+ default:
+- drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n",
++ dev_err(mtk_dp->dev, "invalid aux cmd = %d\n",
+ msg->request);
+ ret = -EINVAL;
+ goto err;
+@@ -2078,7 +2078,7 @@ static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
+ to_access, &msg->reply);
+
+ if (ret) {
+- drm_info(mtk_dp->drm_dev,
++ dev_info(mtk_dp->dev,
+ "Failed to do AUX transfer: %d\n", ret);
+ goto err;
+ }
+--
+2.40.1
+
--- /dev/null
+From 5b998924fef0dbc936ba6f408c1be8434b64f899 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Aug 2023 12:03:40 +0200
+Subject: ext2: fix datatype of block number in ext2_xattr_set2()
+
+From: Georg Ottinger <g.ottinger@gmx.at>
+
+[ Upstream commit e88076348425b7d0491c8c98d8732a7df8de7aa3 ]
+
+I run a small server that uses external hard drives for backups. The
+backup software I use uses ext2 filesystems with 4KiB block size and
+the server is running SELinux and therefore relies on xattr. I recently
+upgraded the hard drives from 4TB to 12TB models. I noticed that after
+transferring some TBs I got a filesystem error "Freeing blocks not in
+datazone - block = 18446744071529317386, count = 1" and the backup
+process stopped. Trying to fix the fs with e2fsck resulted in a
+completely corrupted fs. The error probably came from ext2_free_blocks(),
+and because of the large number 18e19 this problem immediately looked
+like some kind of integer overflow. Whereas the 4TB fs was about 1e9
+blocks, the new 12TB is about 3e9 blocks. So, searching the ext2 code,
+I came across the line in fs/ext2/xattr.c:745 where ext2_new_block()
+is called and the resulting block number is stored in the variable block
+as an int datatype. If a block with a block number greater than
+INT32_MAX is returned, this variable overflows and the call to
+sb_getblk() at line fs/ext2/xattr.c:750 fails, then the call to
+ext2_free_blocks() produces the error.
+
+Signed-off-by: Georg Ottinger <g.ottinger@gmx.at>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Message-Id: <20230815100340.22121-1-g.ottinger@gmx.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext2/xattr.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c
+index 641abfa4b718a..2f89b1073307b 100644
+--- a/fs/ext2/xattr.c
++++ b/fs/ext2/xattr.c
+@@ -744,10 +744,10 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
+ /* We need to allocate a new block */
+ ext2_fsblk_t goal = ext2_group_first_block_no(sb,
+ EXT2_I(inode)->i_block_group);
+- int block = ext2_new_block(inode, goal, &error);
++ ext2_fsblk_t block = ext2_new_block(inode, goal, &error);
+ if (error)
+ goto cleanup;
+- ea_idebug(inode, "creating block %d", block);
++ ea_idebug(inode, "creating block %lu", block);
+
+ new_bh = sb_getblk(sb, block);
+ if (unlikely(!new_bh)) {
+--
+2.40.1
+
--- /dev/null
+From c84478ab355adad970cb9a0af88d41f05d38c419 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Jul 2023 17:05:42 +0300
+Subject: fs/jfs: prevent double-free in dbUnmount() after failed jfs_remount()
+
+From: Andrew Kanner <andrew.kanner@gmail.com>
+
+[ Upstream commit cade5397e5461295f3cb87880534b6a07cafa427 ]
+
+Syzkaller reported the following issue:
+==================================================================
+BUG: KASAN: double-free in slab_free mm/slub.c:3787 [inline]
+BUG: KASAN: double-free in __kmem_cache_free+0x71/0x110 mm/slub.c:3800
+Free of addr ffff888086408000 by task syz-executor.4/12750
+[...]
+Call Trace:
+ <TASK>
+[...]
+ kasan_report_invalid_free+0xac/0xd0 mm/kasan/report.c:482
+ ____kasan_slab_free+0xfb/0x120
+ kasan_slab_free include/linux/kasan.h:177 [inline]
+ slab_free_hook mm/slub.c:1781 [inline]
+ slab_free_freelist_hook+0x12e/0x1a0 mm/slub.c:1807
+ slab_free mm/slub.c:3787 [inline]
+ __kmem_cache_free+0x71/0x110 mm/slub.c:3800
+ dbUnmount+0xf4/0x110 fs/jfs/jfs_dmap.c:264
+ jfs_umount+0x248/0x3b0 fs/jfs/jfs_umount.c:87
+ jfs_put_super+0x86/0x190 fs/jfs/super.c:194
+ generic_shutdown_super+0x130/0x310 fs/super.c:492
+ kill_block_super+0x79/0xd0 fs/super.c:1386
+ deactivate_locked_super+0xa7/0xf0 fs/super.c:332
+ cleanup_mnt+0x494/0x520 fs/namespace.c:1291
+ task_work_run+0x243/0x300 kernel/task_work.c:179
+ resume_user_mode_work include/linux/resume_user_mode.h:49 [inline]
+ exit_to_user_mode_loop+0x124/0x150 kernel/entry/common.c:171
+ exit_to_user_mode_prepare+0xb2/0x140 kernel/entry/common.c:203
+ __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline]
+ syscall_exit_to_user_mode+0x26/0x60 kernel/entry/common.c:296
+ do_syscall_64+0x49/0xb0 arch/x86/entry/common.c:86
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+[...]
+ </TASK>
+
+Allocated by task 13352:
+ kasan_save_stack mm/kasan/common.c:45 [inline]
+ kasan_set_track+0x3d/0x60 mm/kasan/common.c:52
+ ____kasan_kmalloc mm/kasan/common.c:371 [inline]
+ __kasan_kmalloc+0x97/0xb0 mm/kasan/common.c:380
+ kmalloc include/linux/slab.h:580 [inline]
+ dbMount+0x54/0x980 fs/jfs/jfs_dmap.c:164
+ jfs_mount+0x1dd/0x830 fs/jfs/jfs_mount.c:121
+ jfs_fill_super+0x590/0xc50 fs/jfs/super.c:556
+ mount_bdev+0x26c/0x3a0 fs/super.c:1359
+ legacy_get_tree+0xea/0x180 fs/fs_context.c:610
+ vfs_get_tree+0x88/0x270 fs/super.c:1489
+ do_new_mount+0x289/0xad0 fs/namespace.c:3145
+ do_mount fs/namespace.c:3488 [inline]
+ __do_sys_mount fs/namespace.c:3697 [inline]
+ __se_sys_mount+0x2d3/0x3c0 fs/namespace.c:3674
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+Freed by task 13352:
+ kasan_save_stack mm/kasan/common.c:45 [inline]
+ kasan_set_track+0x3d/0x60 mm/kasan/common.c:52
+ kasan_save_free_info+0x27/0x40 mm/kasan/generic.c:518
+ ____kasan_slab_free+0xd6/0x120 mm/kasan/common.c:236
+ kasan_slab_free include/linux/kasan.h:177 [inline]
+ slab_free_hook mm/slub.c:1781 [inline]
+ slab_free_freelist_hook+0x12e/0x1a0 mm/slub.c:1807
+ slab_free mm/slub.c:3787 [inline]
+ __kmem_cache_free+0x71/0x110 mm/slub.c:3800
+ dbUnmount+0xf4/0x110 fs/jfs/jfs_dmap.c:264
+ jfs_mount_rw+0x545/0x740 fs/jfs/jfs_mount.c:247
+ jfs_remount+0x3db/0x710 fs/jfs/super.c:454
+ reconfigure_super+0x3bc/0x7b0 fs/super.c:935
+ vfs_fsconfig_locked fs/fsopen.c:254 [inline]
+ __do_sys_fsconfig fs/fsopen.c:439 [inline]
+ __se_sys_fsconfig+0xad5/0x1060 fs/fsopen.c:314
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+[...]
+
+JFS_SBI(ipbmap->i_sb)->bmap wasn't set to NULL after kfree() in
+dbUnmount().
+
+Syzkaller uses faultinject to reproduce this KASAN double-free
+warning. The issue is triggered if either diMount() or dbMount() fail
+in jfs_remount(), since diUnmount() or dbUnmount() already happened in
+such a case - they will do double-free on next execution: jfs_umount
+or jfs_remount.
+
+Tested on both upstream and jfs-next by syzkaller.
+
+Reported-and-tested-by: syzbot+6a93efb725385bc4b2e9@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/000000000000471f2d05f1ce8bad@google.com/T/
+Link: https://syzkaller.appspot.com/bug?extid=6a93efb725385bc4b2e9
+Signed-off-by: Andrew Kanner <andrew.kanner@gmail.com>
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jfs/jfs_dmap.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
+index bd4ef43b02033..e9d075cbd71ad 100644
+--- a/fs/jfs/jfs_dmap.c
++++ b/fs/jfs/jfs_dmap.c
+@@ -269,6 +269,7 @@ int dbUnmount(struct inode *ipbmap, int mounterror)
+
+ /* free the memory for the in-memory bmap. */
+ kfree(bmp);
++ JFS_SBI(ipbmap->i_sb)->bmap = NULL;
+
+ return (0);
+ }
+--
+2.40.1
+
--- /dev/null
+From 2ded7288be8ae97457ea6c2b1ac539f079707391 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Jun 2023 12:19:23 -0700
+Subject: hw_breakpoint: fix single-stepping when using bpf_overflow_handler
+
+From: Tomislav Novak <tnovak@meta.com>
+
+[ Upstream commit d11a69873d9a7435fe6a48531e165ab80a8b1221 ]
+
+Arm platforms use is_default_overflow_handler() to determine if the
+hw_breakpoint code should single-step over the breakpoint trigger or
+let the custom handler deal with it.
+
+Since bpf_overflow_handler() currently isn't recognized as a default
+handler, attaching a BPF program to a PERF_TYPE_BREAKPOINT event causes
+it to keep firing (the instruction triggering the data abort exception
+is never skipped). For example:
+
+ # bpftrace -e 'watchpoint:0x10000:4:w { print("hit") }' -c ./test
+ Attaching 1 probe...
+ hit
+ hit
+ [...]
+ ^C
+
+(./test performs a single 4-byte store to 0x10000)
+
+This patch replaces the check with uses_default_overflow_handler(),
+which accounts for the bpf_overflow_handler() case by also testing
+if one of the perf_event_output functions gets invoked indirectly,
+via orig_default_handler.
+
+Signed-off-by: Tomislav Novak <tnovak@meta.com>
+Tested-by: Samuel Gosselin <sgosselin@google.com> # arm64
+Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
+Acked-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/linux-arm-kernel/20220923203644.2731604-1-tnovak@fb.com/
+Link: https://lore.kernel.org/r/20230605191923.1219974-1-tnovak@meta.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/kernel/hw_breakpoint.c | 8 ++++----
+ arch/arm64/kernel/hw_breakpoint.c | 4 ++--
+ include/linux/perf_event.h | 22 +++++++++++++++++++---
+ 3 files changed, 25 insertions(+), 9 deletions(-)
+
+diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
+index 054e9199f30db..dc0fb7a813715 100644
+--- a/arch/arm/kernel/hw_breakpoint.c
++++ b/arch/arm/kernel/hw_breakpoint.c
+@@ -626,7 +626,7 @@ int hw_breakpoint_arch_parse(struct perf_event *bp,
+ hw->address &= ~alignment_mask;
+ hw->ctrl.len <<= offset;
+
+- if (is_default_overflow_handler(bp)) {
++ if (uses_default_overflow_handler(bp)) {
+ /*
+ * Mismatch breakpoints are required for single-stepping
+ * breakpoints.
+@@ -798,7 +798,7 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,
+ * Otherwise, insert a temporary mismatch breakpoint so that
+ * we can single-step over the watchpoint trigger.
+ */
+- if (!is_default_overflow_handler(wp))
++ if (!uses_default_overflow_handler(wp))
+ continue;
+ step:
+ enable_single_step(wp, instruction_pointer(regs));
+@@ -811,7 +811,7 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,
+ info->trigger = addr;
+ pr_debug("watchpoint fired: address = 0x%x\n", info->trigger);
+ perf_bp_event(wp, regs);
+- if (is_default_overflow_handler(wp))
++ if (uses_default_overflow_handler(wp))
+ enable_single_step(wp, instruction_pointer(regs));
+ }
+
+@@ -886,7 +886,7 @@ static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs)
+ info->trigger = addr;
+ pr_debug("breakpoint fired: address = 0x%x\n", addr);
+ perf_bp_event(bp, regs);
+- if (is_default_overflow_handler(bp))
++ if (uses_default_overflow_handler(bp))
+ enable_single_step(bp, addr);
+ goto unlock;
+ }
+diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
+index b29a311bb0552..9659a9555c63a 100644
+--- a/arch/arm64/kernel/hw_breakpoint.c
++++ b/arch/arm64/kernel/hw_breakpoint.c
+@@ -654,7 +654,7 @@ static int breakpoint_handler(unsigned long unused, unsigned long esr,
+ perf_bp_event(bp, regs);
+
+ /* Do we need to handle the stepping? */
+- if (is_default_overflow_handler(bp))
++ if (uses_default_overflow_handler(bp))
+ step = 1;
+ unlock:
+ rcu_read_unlock();
+@@ -733,7 +733,7 @@ static u64 get_distance_from_watchpoint(unsigned long addr, u64 val,
+ static int watchpoint_report(struct perf_event *wp, unsigned long addr,
+ struct pt_regs *regs)
+ {
+- int step = is_default_overflow_handler(wp);
++ int step = uses_default_overflow_handler(wp);
+ struct arch_hw_breakpoint *info = counter_arch_bp(wp);
+
+ info->trigger = addr;
+diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
+index 0031f7b4d9aba..63fae3c7ae430 100644
+--- a/include/linux/perf_event.h
++++ b/include/linux/perf_event.h
+@@ -1139,15 +1139,31 @@ extern int perf_event_output(struct perf_event *event,
+ struct pt_regs *regs);
+
+ static inline bool
+-is_default_overflow_handler(struct perf_event *event)
++__is_default_overflow_handler(perf_overflow_handler_t overflow_handler)
+ {
+- if (likely(event->overflow_handler == perf_event_output_forward))
++ if (likely(overflow_handler == perf_event_output_forward))
+ return true;
+- if (unlikely(event->overflow_handler == perf_event_output_backward))
++ if (unlikely(overflow_handler == perf_event_output_backward))
+ return true;
+ return false;
+ }
+
++#define is_default_overflow_handler(event) \
++ __is_default_overflow_handler((event)->overflow_handler)
++
++#ifdef CONFIG_BPF_SYSCALL
++static inline bool uses_default_overflow_handler(struct perf_event *event)
++{
++ if (likely(is_default_overflow_handler(event)))
++ return true;
++
++ return __is_default_overflow_handler(event->orig_overflow_handler);
++}
++#else
++#define uses_default_overflow_handler(event) \
++ is_default_overflow_handler(event)
++#endif
++
+ extern void
+ perf_event_header__init_id(struct perf_event_header *header,
+ struct perf_sample_data *data,
+--
+2.40.1
+
--- /dev/null
+From ad5a9a949de04696a97213be0884c012994bd7d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jul 2023 13:03:28 +0200
+Subject: ice: Don't tx before switchdev is fully configured
+
+From: Wojciech Drewek <wojciech.drewek@intel.com>
+
+[ Upstream commit 7aa529a69e92b9aff585e569d5003f7c15d8d60b ]
+
+There is possibility that ice_eswitch_port_start_xmit might be
+called while some resources are still not allocated which might
+cause NULL pointer dereference. Fix this by checking if switchdev
+configuration was finished.
+
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com>
+Tested-by: Sujai Buvaneswaran <sujai.buvaneswaran@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_eswitch.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_eswitch.c b/drivers/net/ethernet/intel/ice/ice_eswitch.c
+index 2ffe5708a045b..7de4a8a4b563c 100644
+--- a/drivers/net/ethernet/intel/ice/ice_eswitch.c
++++ b/drivers/net/ethernet/intel/ice/ice_eswitch.c
+@@ -361,6 +361,9 @@ ice_eswitch_port_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+ np = netdev_priv(netdev);
+ vsi = np->vsi;
+
++ if (!vsi || !ice_is_switchdev_running(vsi->back))
++ return NETDEV_TX_BUSY;
++
+ if (ice_is_reset_in_progress(vsi->back->state) ||
+ test_bit(ICE_VF_DIS, vsi->back->state))
+ return NETDEV_TX_BUSY;
+--
+2.40.1
+
--- /dev/null
+From 32a3da93dbb955c7a7e4fab7bb0b9a29dcef4314 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Aug 2023 10:11:40 -0700
+Subject: interconnect: Fix locking for runpm vs reclaim
+
+From: Rob Clark <robdclark@chromium.org>
+
+[ Upstream commit af42269c3523492d71ebbe11fefae2653e9cdc78 ]
+
+For cases where icc_bw_set() can be called in callbaths that could
+deadlock against shrinker/reclaim, such as runpm resume, we need to
+decouple the icc locking. Introduce a new icc_bw_lock for cases where
+we need to serialize bw aggregation and update to decouple that from
+paths that require memory allocation such as node/link creation/
+destruction.
+
+Fixes this lockdep splat:
+
+ ======================================================
+ WARNING: possible circular locking dependency detected
+ 6.2.0-rc8-debug+ #554 Not tainted
+ ------------------------------------------------------
+ ring0/132 is trying to acquire lock:
+ ffffff80871916d0 (&gmu->lock){+.+.}-{3:3}, at: a6xx_pm_resume+0xf0/0x234
+
+ but task is already holding lock:
+ ffffffdb5aee57e8 (dma_fence_map){++++}-{0:0}, at: msm_job_run+0x68/0x150
+
+ which lock already depends on the new lock.
+
+ the existing dependency chain (in reverse order) is:
+
+ -> #4 (dma_fence_map){++++}-{0:0}:
+ __dma_fence_might_wait+0x74/0xc0
+ dma_resv_lockdep+0x1f4/0x2f4
+ do_one_initcall+0x104/0x2bc
+ kernel_init_freeable+0x344/0x34c
+ kernel_init+0x30/0x134
+ ret_from_fork+0x10/0x20
+
+ -> #3 (mmu_notifier_invalidate_range_start){+.+.}-{0:0}:
+ fs_reclaim_acquire+0x80/0xa8
+ slab_pre_alloc_hook.constprop.0+0x40/0x25c
+ __kmem_cache_alloc_node+0x60/0x1cc
+ __kmalloc+0xd8/0x100
+ topology_parse_cpu_capacity+0x8c/0x178
+ get_cpu_for_node+0x88/0xc4
+ parse_cluster+0x1b0/0x28c
+ parse_cluster+0x8c/0x28c
+ init_cpu_topology+0x168/0x188
+ smp_prepare_cpus+0x24/0xf8
+ kernel_init_freeable+0x18c/0x34c
+ kernel_init+0x30/0x134
+ ret_from_fork+0x10/0x20
+
+ -> #2 (fs_reclaim){+.+.}-{0:0}:
+ __fs_reclaim_acquire+0x3c/0x48
+ fs_reclaim_acquire+0x54/0xa8
+ slab_pre_alloc_hook.constprop.0+0x40/0x25c
+ __kmem_cache_alloc_node+0x60/0x1cc
+ __kmalloc+0xd8/0x100
+ kzalloc.constprop.0+0x14/0x20
+ icc_node_create_nolock+0x4c/0xc4
+ icc_node_create+0x38/0x58
+ qcom_icc_rpmh_probe+0x1b8/0x248
+ platform_probe+0x70/0xc4
+ really_probe+0x158/0x290
+ __driver_probe_device+0xc8/0xe0
+ driver_probe_device+0x44/0x100
+ __driver_attach+0xf8/0x108
+ bus_for_each_dev+0x78/0xc4
+ driver_attach+0x2c/0x38
+ bus_add_driver+0xd0/0x1d8
+ driver_register+0xbc/0xf8
+ __platform_driver_register+0x30/0x3c
+ qnoc_driver_init+0x24/0x30
+ do_one_initcall+0x104/0x2bc
+ kernel_init_freeable+0x344/0x34c
+ kernel_init+0x30/0x134
+ ret_from_fork+0x10/0x20
+
+ -> #1 (icc_lock){+.+.}-{3:3}:
+ __mutex_lock+0xcc/0x3c8
+ mutex_lock_nested+0x30/0x44
+ icc_set_bw+0x88/0x2b4
+ _set_opp_bw+0x8c/0xd8
+ _set_opp+0x19c/0x300
+ dev_pm_opp_set_opp+0x84/0x94
+ a6xx_gmu_resume+0x18c/0x804
+ a6xx_pm_resume+0xf8/0x234
+ adreno_runtime_resume+0x2c/0x38
+ pm_generic_runtime_resume+0x30/0x44
+ __rpm_callback+0x15c/0x174
+ rpm_callback+0x78/0x7c
+ rpm_resume+0x318/0x524
+ __pm_runtime_resume+0x78/0xbc
+ adreno_load_gpu+0xc4/0x17c
+ msm_open+0x50/0x120
+ drm_file_alloc+0x17c/0x228
+ drm_open_helper+0x74/0x118
+ drm_open+0xa0/0x144
+ drm_stub_open+0xd4/0xe4
+ chrdev_open+0x1b8/0x1e4
+ do_dentry_open+0x2f8/0x38c
+ vfs_open+0x34/0x40
+ path_openat+0x64c/0x7b4
+ do_filp_open+0x54/0xc4
+ do_sys_openat2+0x9c/0x100
+ do_sys_open+0x50/0x7c
+ __arm64_sys_openat+0x28/0x34
+ invoke_syscall+0x8c/0x128
+ el0_svc_common.constprop.0+0xa0/0x11c
+ do_el0_svc+0xac/0xbc
+ el0_svc+0x48/0xa0
+ el0t_64_sync_handler+0xac/0x13c
+ el0t_64_sync+0x190/0x194
+
+ -> #0 (&gmu->lock){+.+.}-{3:3}:
+ __lock_acquire+0xe00/0x1060
+ lock_acquire+0x1e0/0x2f8
+ __mutex_lock+0xcc/0x3c8
+ mutex_lock_nested+0x30/0x44
+ a6xx_pm_resume+0xf0/0x234
+ adreno_runtime_resume+0x2c/0x38
+ pm_generic_runtime_resume+0x30/0x44
+ __rpm_callback+0x15c/0x174
+ rpm_callback+0x78/0x7c
+ rpm_resume+0x318/0x524
+ __pm_runtime_resume+0x78/0xbc
+ pm_runtime_get_sync.isra.0+0x14/0x20
+ msm_gpu_submit+0x58/0x178
+ msm_job_run+0x78/0x150
+ drm_sched_main+0x290/0x370
+ kthread+0xf0/0x100
+ ret_from_fork+0x10/0x20
+
+ other info that might help us debug this:
+
+ Chain exists of:
+ &gmu->lock --> mmu_notifier_invalidate_range_start --> dma_fence_map
+
+ Possible unsafe locking scenario:
+
+ CPU0 CPU1
+ ---- ----
+ lock(dma_fence_map);
+ lock(mmu_notifier_invalidate_range_start);
+ lock(dma_fence_map);
+ lock(&gmu->lock);
+
+ *** DEADLOCK ***
+
+ 2 locks held by ring0/132:
+ #0: ffffff8087191170 (&gpu->lock){+.+.}-{3:3}, at: msm_job_run+0x64/0x150
+ #1: ffffffdb5aee57e8 (dma_fence_map){++++}-{0:0}, at: msm_job_run+0x68/0x150
+
+ stack backtrace:
+ CPU: 7 PID: 132 Comm: ring0 Not tainted 6.2.0-rc8-debug+ #554
+ Hardware name: Google Lazor (rev1 - 2) with LTE (DT)
+ Call trace:
+ dump_backtrace.part.0+0xb4/0xf8
+ show_stack+0x20/0x38
+ dump_stack_lvl+0x9c/0xd0
+ dump_stack+0x18/0x34
+ print_circular_bug+0x1b4/0x1f0
+ check_noncircular+0x78/0xac
+ __lock_acquire+0xe00/0x1060
+ lock_acquire+0x1e0/0x2f8
+ __mutex_lock+0xcc/0x3c8
+ mutex_lock_nested+0x30/0x44
+ a6xx_pm_resume+0xf0/0x234
+ adreno_runtime_resume+0x2c/0x38
+ pm_generic_runtime_resume+0x30/0x44
+ __rpm_callback+0x15c/0x174
+ rpm_callback+0x78/0x7c
+ rpm_resume+0x318/0x524
+ __pm_runtime_resume+0x78/0xbc
+ pm_runtime_get_sync.isra.0+0x14/0x20
+ msm_gpu_submit+0x58/0x178
+ msm_job_run+0x78/0x150
+ drm_sched_main+0x290/0x370
+ kthread+0xf0/0x100
+ ret_from_fork+0x10/0x20
+
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Link: https://lore.kernel.org/r/20230807171148.210181-7-robdclark@gmail.com
+Signed-off-by: Georgi Djakov <djakov@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/interconnect/core.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c
+index cfa52c6369d05..f4a493d78ee9a 100644
+--- a/drivers/interconnect/core.c
++++ b/drivers/interconnect/core.c
+@@ -29,6 +29,7 @@ static LIST_HEAD(icc_providers);
+ static int providers_count;
+ static bool synced_state;
+ static DEFINE_MUTEX(icc_lock);
++static DEFINE_MUTEX(icc_bw_lock);
+ static struct dentry *icc_debugfs_dir;
+
+ static void icc_summary_show_one(struct seq_file *s, struct icc_node *n)
+@@ -632,7 +633,7 @@ int icc_set_bw(struct icc_path *path, u32 avg_bw, u32 peak_bw)
+ if (WARN_ON(IS_ERR(path) || !path->num_nodes))
+ return -EINVAL;
+
+- mutex_lock(&icc_lock);
++ mutex_lock(&icc_bw_lock);
+
+ old_avg = path->reqs[0].avg_bw;
+ old_peak = path->reqs[0].peak_bw;
+@@ -664,7 +665,7 @@ int icc_set_bw(struct icc_path *path, u32 avg_bw, u32 peak_bw)
+ apply_constraints(path);
+ }
+
+- mutex_unlock(&icc_lock);
++ mutex_unlock(&icc_bw_lock);
+
+ trace_icc_set_bw_end(path, ret);
+
+@@ -967,6 +968,7 @@ void icc_node_add(struct icc_node *node, struct icc_provider *provider)
+ return;
+
+ mutex_lock(&icc_lock);
++ mutex_lock(&icc_bw_lock);
+
+ node->provider = provider;
+ list_add_tail(&node->node_list, &provider->nodes);
+@@ -992,6 +994,7 @@ void icc_node_add(struct icc_node *node, struct icc_provider *provider)
+ node->avg_bw = 0;
+ node->peak_bw = 0;
+
++ mutex_unlock(&icc_bw_lock);
+ mutex_unlock(&icc_lock);
+ }
+ EXPORT_SYMBOL_GPL(icc_node_add);
+@@ -1129,6 +1132,7 @@ void icc_sync_state(struct device *dev)
+ return;
+
+ mutex_lock(&icc_lock);
++ mutex_lock(&icc_bw_lock);
+ synced_state = true;
+ list_for_each_entry(p, &icc_providers, provider_list) {
+ dev_dbg(p->dev, "interconnect provider is in synced state\n");
+--
+2.40.1
+
--- /dev/null
+From 7e2cced6e0e3f52847a0c80db7d996c1eacc777a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Dec 2022 20:46:28 +0800
+Subject: jfs: fix invalid free of JFS_IP(ipimap)->i_imap in diUnmount
+
+From: Liu Shixin via Jfs-discussion <jfs-discussion@lists.sourceforge.net>
+
+[ Upstream commit 6e2bda2c192d0244b5a78b787ef20aa10cb319b7 ]
+
+syzbot found an invalid-free in diUnmount:
+
+BUG: KASAN: double-free in slab_free mm/slub.c:3661 [inline]
+BUG: KASAN: double-free in __kmem_cache_free+0x71/0x110 mm/slub.c:3674
+Free of addr ffff88806f410000 by task syz-executor131/3632
+
+ CPU: 0 PID: 3632 Comm: syz-executor131 Not tainted 6.1.0-rc7-syzkaller-00012-gca57f02295f1 #0
+ Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022
+ Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0x1b1/0x28e lib/dump_stack.c:106
+ print_address_description+0x74/0x340 mm/kasan/report.c:284
+ print_report+0x107/0x1f0 mm/kasan/report.c:395
+ kasan_report_invalid_free+0xac/0xd0 mm/kasan/report.c:460
+ ____kasan_slab_free+0xfb/0x120
+ kasan_slab_free include/linux/kasan.h:177 [inline]
+ slab_free_hook mm/slub.c:1724 [inline]
+ slab_free_freelist_hook+0x12e/0x1a0 mm/slub.c:1750
+ slab_free mm/slub.c:3661 [inline]
+ __kmem_cache_free+0x71/0x110 mm/slub.c:3674
+ diUnmount+0xef/0x100 fs/jfs/jfs_imap.c:195
+ jfs_umount+0x108/0x370 fs/jfs/jfs_umount.c:63
+ jfs_put_super+0x86/0x190 fs/jfs/super.c:194
+ generic_shutdown_super+0x130/0x310 fs/super.c:492
+ kill_block_super+0x79/0xd0 fs/super.c:1428
+ deactivate_locked_super+0xa7/0xf0 fs/super.c:332
+ cleanup_mnt+0x494/0x520 fs/namespace.c:1186
+ task_work_run+0x243/0x300 kernel/task_work.c:179
+ exit_task_work include/linux/task_work.h:38 [inline]
+ do_exit+0x664/0x2070 kernel/exit.c:820
+ do_group_exit+0x1fd/0x2b0 kernel/exit.c:950
+ __do_sys_exit_group kernel/exit.c:961 [inline]
+ __se_sys_exit_group kernel/exit.c:959 [inline]
+ __x64_sys_exit_group+0x3b/0x40 kernel/exit.c:959
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+[...]
+
+JFS_IP(ipimap)->i_imap is not setting to NULL after free in diUnmount.
+If jfs_remount() free JFS_IP(ipimap)->i_imap but then failed at diMount().
+JFS_IP(ipimap)->i_imap will be freed once again.
+Fix this problem by setting JFS_IP(ipimap)->i_imap to NULL after free.
+
+Reported-by: syzbot+90a11e6b1e810785c6ff@syzkaller.appspotmail.com
+Signed-off-by: Liu Shixin <liushixin2@huawei.com>
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jfs/jfs_imap.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
+index 799d3837e7c2b..4899663996d81 100644
+--- a/fs/jfs/jfs_imap.c
++++ b/fs/jfs/jfs_imap.c
+@@ -193,6 +193,7 @@ int diUnmount(struct inode *ipimap, int mounterror)
+ * free in-memory control structure
+ */
+ kfree(imap);
++ JFS_IP(ipimap)->i_imap = NULL;
+
+ return (0);
+ }
+--
+2.40.1
+
--- /dev/null
+From a7a1b1d0a2cc600c3f004b705b90847ad2f0e6de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jun 2023 09:23:21 -0300
+Subject: kernel/fork: beware of __put_task_struct() calling context
+
+From: Wander Lairson Costa <wander@redhat.com>
+
+[ Upstream commit d243b34459cea30cfe5f3a9b2feb44e7daff9938 ]
+
+Under PREEMPT_RT, __put_task_struct() indirectly acquires sleeping
+locks. Therefore, it can't be called from an non-preemptible context.
+
+One practical example is splat inside inactive_task_timer(), which is
+called in a interrupt context:
+
+ CPU: 1 PID: 2848 Comm: life Kdump: loaded Tainted: G W ---------
+ Hardware name: HP ProLiant DL388p Gen8, BIOS P70 07/15/2012
+ Call Trace:
+ dump_stack_lvl+0x57/0x7d
+ mark_lock_irq.cold+0x33/0xba
+ mark_lock+0x1e7/0x400
+ mark_usage+0x11d/0x140
+ __lock_acquire+0x30d/0x930
+ lock_acquire.part.0+0x9c/0x210
+ rt_spin_lock+0x27/0xe0
+ refill_obj_stock+0x3d/0x3a0
+ kmem_cache_free+0x357/0x560
+ inactive_task_timer+0x1ad/0x340
+ __run_hrtimer+0x8a/0x1a0
+ __hrtimer_run_queues+0x91/0x130
+ hrtimer_interrupt+0x10f/0x220
+ __sysvec_apic_timer_interrupt+0x7b/0xd0
+ sysvec_apic_timer_interrupt+0x4f/0xd0
+ asm_sysvec_apic_timer_interrupt+0x12/0x20
+ RIP: 0033:0x7fff196bf6f5
+
+Instead of calling __put_task_struct() directly, we defer it using
+call_rcu(). A more natural approach would use a workqueue, but since
+in PREEMPT_RT, we can't allocate dynamic memory from atomic context,
+the code would become more complex because we would need to put the
+work_struct instance in the task_struct and initialize it when we
+allocate a new task_struct.
+
+The issue is reproducible with stress-ng:
+
+ while true; do
+ stress-ng --sched deadline --sched-period 1000000000 \
+ --sched-runtime 800000000 --sched-deadline \
+ 1000000000 --mmapfork 23 -t 20
+ done
+
+Reported-by: Hu Chunyu <chuhu@redhat.com>
+Suggested-by: Oleg Nesterov <oleg@redhat.com>
+Suggested-by: Valentin Schneider <vschneid@redhat.com>
+Suggested-by: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: Wander Lairson Costa <wander@redhat.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20230614122323.37957-2-wander@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/sched/task.h | 28 +++++++++++++++++++++++++++-
+ kernel/fork.c | 8 ++++++++
+ 2 files changed, 35 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h
+index 357e0068497c1..7291fb6399d2a 100644
+--- a/include/linux/sched/task.h
++++ b/include/linux/sched/task.h
+@@ -112,10 +112,36 @@ static inline struct task_struct *get_task_struct(struct task_struct *t)
+ }
+
+ extern void __put_task_struct(struct task_struct *t);
++extern void __put_task_struct_rcu_cb(struct rcu_head *rhp);
+
+ static inline void put_task_struct(struct task_struct *t)
+ {
+- if (refcount_dec_and_test(&t->usage))
++ if (!refcount_dec_and_test(&t->usage))
++ return;
++
++ /*
++ * under PREEMPT_RT, we can't call put_task_struct
++ * in atomic context because it will indirectly
++ * acquire sleeping locks.
++ *
++ * call_rcu() will schedule delayed_put_task_struct_rcu()
++ * to be called in process context.
++ *
++ * __put_task_struct() is called when
++ * refcount_dec_and_test(&t->usage) succeeds.
++ *
++ * This means that it can't "conflict" with
++ * put_task_struct_rcu_user() which abuses ->rcu the same
++ * way; rcu_users has a reference so task->usage can't be
++ * zero after rcu_users 1 -> 0 transition.
++ *
++ * delayed_free_task() also uses ->rcu, but it is only called
++ * when it fails to fork a process. Therefore, there is no
++ * way it can conflict with put_task_struct().
++ */
++ if (IS_ENABLED(CONFIG_PREEMPT_RT) && !preemptible())
++ call_rcu(&t->rcu, __put_task_struct_rcu_cb);
++ else
+ __put_task_struct(t);
+ }
+
+diff --git a/kernel/fork.c b/kernel/fork.c
+index 41950ff90aa34..85617928041cf 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -852,6 +852,14 @@ void __put_task_struct(struct task_struct *tsk)
+ }
+ EXPORT_SYMBOL_GPL(__put_task_struct);
+
++void __put_task_struct_rcu_cb(struct rcu_head *rhp)
++{
++ struct task_struct *task = container_of(rhp, struct task_struct, rcu);
++
++ __put_task_struct(task);
++}
++EXPORT_SYMBOL_GPL(__put_task_struct_rcu_cb);
++
+ void __init __weak arch_task_cache_init(void) { }
+
+ /*
+--
+2.40.1
+
--- /dev/null
+From 78ac73589ae98ae583de881317d617cf6a226b63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 5 Aug 2023 16:41:13 +0800
+Subject: kobject: Add sanity check for kset->kobj.ktype in kset_register()
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+[ Upstream commit 4d0fe8c52bb3029d83e323c961221156ab98680b ]
+
+When I register a kset in the following way:
+ static struct kset my_kset;
+ kobject_set_name(&my_kset.kobj, "my_kset");
+ ret = kset_register(&my_kset);
+
+A null pointer dereference exception is occurred:
+[ 4453.568337] Unable to handle kernel NULL pointer dereference at \
+virtual address 0000000000000028
+... ...
+[ 4453.810361] Call trace:
+[ 4453.813062] kobject_get_ownership+0xc/0x34
+[ 4453.817493] kobject_add_internal+0x98/0x274
+[ 4453.822005] kset_register+0x5c/0xb4
+[ 4453.825820] my_kobj_init+0x44/0x1000 [my_kset]
+... ...
+
+Because I didn't initialize my_kset.kobj.ktype.
+
+According to the description in Documentation/core-api/kobject.rst:
+ - A ktype is the type of object that embeds a kobject. Every structure
+ that embeds a kobject needs a corresponding ktype.
+
+So add sanity check to make sure kset->kobj.ktype is not NULL.
+
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Link: https://lore.kernel.org/r/20230805084114.1298-2-thunder.leizhen@huaweicloud.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/kobject.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/lib/kobject.c b/lib/kobject.c
+index aa375a5d94419..207fd22ad3bde 100644
+--- a/lib/kobject.c
++++ b/lib/kobject.c
+@@ -850,6 +850,11 @@ int kset_register(struct kset *k)
+ if (!k)
+ return -EINVAL;
+
++ if (!k->kobj.ktype) {
++ pr_err("must have a ktype to be initialized properly!\n");
++ return -EINVAL;
++ }
++
+ kset_init(k);
+ err = kobject_add_internal(&k->kobj);
+ if (err)
+--
+2.40.1
+
--- /dev/null
+From 69372b5099efe3d2976c539e271f3e6358395f3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Aug 2023 12:38:40 -0700
+Subject: libbpf: Free btf_vmlinux when closing bpf_object
+
+From: Hao Luo <haoluo@google.com>
+
+[ Upstream commit 29d67fdebc42af6466d1909c60fdd1ef4f3e5240 ]
+
+I hit a memory leak when testing bpf_program__set_attach_target().
+Basically, set_attach_target() may allocate btf_vmlinux, for example,
+when setting attach target for bpf_iter programs. But btf_vmlinux
+is freed only in bpf_object_load(), which means if we only open
+bpf object but not load it, setting attach target may leak
+btf_vmlinux.
+
+So let's free btf_vmlinux in bpf_object__close() anyway.
+
+Signed-off-by: Hao Luo <haoluo@google.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20230822193840.1509809-1-haoluo@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/libbpf.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index eeb2693128d8a..10f15a3e3a95e 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -8173,6 +8173,7 @@ void bpf_object__close(struct bpf_object *obj)
+ bpf_object__elf_finish(obj);
+ bpf_object_unload(obj);
+ btf__free(obj->btf);
++ btf__free(obj->btf_vmlinux);
+ btf_ext__free(obj->btf_ext);
+
+ for (i = 0; i < obj->nr_maps; i++)
+--
+2.40.1
+
--- /dev/null
+From 2b98fe1feb4a4e9f102f5a80b851cd59fffa109e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jul 2023 13:19:04 +0800
+Subject: locks: fix KASAN: use-after-free in
+ trace_event_raw_event_filelock_lock
+
+From: Will Shiu <Will.Shiu@mediatek.com>
+
+[ Upstream commit 74f6f5912693ce454384eaeec48705646a21c74f ]
+
+As following backtrace, the struct file_lock request , in posix_lock_inode
+is free before ftrace function using.
+Replace the ftrace function ahead free flow could fix the use-after-free
+issue.
+
+[name:report&]===============================================
+BUG:KASAN: use-after-free in trace_event_raw_event_filelock_lock+0x80/0x12c
+[name:report&]Read at addr f6ffff8025622620 by task NativeThread/16753
+[name:report_hw_tags&]Pointer tag: [f6], memory tag: [fe]
+[name:report&]
+BT:
+Hardware name: MT6897 (DT)
+Call trace:
+ dump_backtrace+0xf8/0x148
+ show_stack+0x18/0x24
+ dump_stack_lvl+0x60/0x7c
+ print_report+0x2c8/0xa08
+ kasan_report+0xb0/0x120
+ __do_kernel_fault+0xc8/0x248
+ do_bad_area+0x30/0xdc
+ do_tag_check_fault+0x1c/0x30
+ do_mem_abort+0x58/0xbc
+ el1_abort+0x3c/0x5c
+ el1h_64_sync_handler+0x54/0x90
+ el1h_64_sync+0x68/0x6c
+ trace_event_raw_event_filelock_lock+0x80/0x12c
+ posix_lock_inode+0xd0c/0xd60
+ do_lock_file_wait+0xb8/0x190
+ fcntl_setlk+0x2d8/0x440
+...
+[name:report&]
+[name:report&]Allocated by task 16752:
+...
+ slab_post_alloc_hook+0x74/0x340
+ kmem_cache_alloc+0x1b0/0x2f0
+ posix_lock_inode+0xb0/0xd60
+...
+ [name:report&]
+ [name:report&]Freed by task 16752:
+...
+ kmem_cache_free+0x274/0x5b0
+ locks_dispose_list+0x3c/0x148
+ posix_lock_inode+0xc40/0xd60
+ do_lock_file_wait+0xb8/0x190
+ fcntl_setlk+0x2d8/0x440
+ do_fcntl+0x150/0xc18
+...
+
+Signed-off-by: Will Shiu <Will.Shiu@mediatek.com>
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/locks.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/locks.c b/fs/locks.c
+index 240b9309ed6d5..1047ab2b15e96 100644
+--- a/fs/locks.c
++++ b/fs/locks.c
+@@ -1300,6 +1300,7 @@ static int posix_lock_inode(struct inode *inode, struct file_lock *request,
+ out:
+ spin_unlock(&ctx->flc_lock);
+ percpu_up_read(&file_rwsem);
++ trace_posix_lock_inode(inode, request, error);
+ /*
+ * Free any unused locks.
+ */
+@@ -1308,7 +1309,6 @@ static int posix_lock_inode(struct inode *inode, struct file_lock *request,
+ if (new_fl2)
+ locks_free_lock(new_fl2);
+ locks_dispose_list(&dispose);
+- trace_posix_lock_inode(inode, request, error);
+
+ return error;
+ }
+--
+2.40.1
+
--- /dev/null
+From 518dd7048f6d199115a620433656f9f921216b32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Sep 2023 14:25:23 -0700
+Subject: md/raid1: fix error: ISO C90 forbids mixed declarations
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nigel Croxon <ncroxon@redhat.com>
+
+[ Upstream commit df203da47f4428bc286fc99318936416253a321c ]
+
+There is a compile error when this commit is added:
+md: raid1: fix potential OOB in raid1_remove_disk()
+
+drivers/md/raid1.c: In function 'raid1_remove_disk':
+drivers/md/raid1.c:1844:9: error: ISO C90 forbids mixed declarations
+and code [-Werror=declaration-after-statement]
+1844 | struct raid1_info *p = conf->mirrors + number;
+ | ^~~~~~
+
+That's because the new code was inserted before the struct.
+The change is move the struct command above this commit.
+
+Fixes: 8b0472b50bcf ("md: raid1: fix potential OOB in raid1_remove_disk()")
+Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/46d929d0-2aab-4cf2-b2bf-338963e8ba5a@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid1.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index 72303c6201747..30f906a67def4 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -1826,12 +1826,11 @@ static int raid1_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
+ struct r1conf *conf = mddev->private;
+ int err = 0;
+ int number = rdev->raid_disk;
++ struct raid1_info *p = conf->mirrors + number;
+
+ if (unlikely(number >= conf->raid_disks))
+ goto abort;
+
+- struct raid1_info *p = conf->mirrors + number;
+-
+ if (rdev != p->rdev)
+ p = conf->mirrors + conf->raid_disks + number;
+
+--
+2.40.1
+
--- /dev/null
+From dde65157ebddaba18a758f030ee2c9a9fd77f3e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Jul 2023 15:53:53 +0800
+Subject: md: raid1: fix potential OOB in raid1_remove_disk()
+
+From: Zhang Shurong <zhang_shurong@foxmail.com>
+
+[ Upstream commit 8b0472b50bcf0f19a5119b00a53b63579c8e1e4d ]
+
+If rddev->raid_disk is greater than mddev->raid_disks, there will be
+an out-of-bounds in raid1_remove_disk(). We have already found
+similar reports as follows:
+
+1) commit d17f744e883b ("md-raid10: fix KASAN warning")
+2) commit 1ebc2cec0b7d ("dm raid: fix KASAN warning in raid5_remove_disk")
+
+Fix this bug by checking whether the "number" variable is
+valid.
+
+Signed-off-by: Zhang Shurong <zhang_shurong@foxmail.com>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/tencent_0D24426FAC6A21B69AC0C03CE4143A508F09@qq.com
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid1.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index ac64c587191b9..72303c6201747 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -1826,6 +1826,10 @@ static int raid1_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
+ struct r1conf *conf = mddev->private;
+ int err = 0;
+ int number = rdev->raid_disk;
++
++ if (unlikely(number >= conf->raid_disks))
++ goto abort;
++
+ struct raid1_info *p = conf->mirrors + number;
+
+ if (rdev != p->rdev)
+--
+2.40.1
+
--- /dev/null
+From 657a48183816623a161833003ee676c49902959b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Jul 2023 23:24:11 +0800
+Subject: media: af9005: Fix null-ptr-deref in af9005_i2c_xfer
+
+From: Zhang Shurong <zhang_shurong@foxmail.com>
+
+[ Upstream commit f4ee84f27625ce1fdf41e8483fa0561a1b837d10 ]
+
+In af9005_i2c_xfer, msg is controlled by user. When msg[i].buf
+is null and msg[i].len is zero, former checks on msg[i].buf would be
+passed. Malicious data finally reach af9005_i2c_xfer. If accessing
+msg[i].buf[0] without sanity check, null ptr deref would happen.
+We add check on msg[i].len to prevent crash.
+
+Similar commit:
+commit 0ed554fd769a
+("media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer()")
+
+Signed-off-by: Zhang Shurong <zhang_shurong@foxmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/dvb-usb/af9005.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/media/usb/dvb-usb/af9005.c b/drivers/media/usb/dvb-usb/af9005.c
+index 0827bf3d4e8c7..13604e6acdb83 100644
+--- a/drivers/media/usb/dvb-usb/af9005.c
++++ b/drivers/media/usb/dvb-usb/af9005.c
+@@ -422,6 +422,10 @@ static int af9005_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+ if (ret == 0)
+ ret = 2;
+ } else {
++ if (msg[0].len < 2) {
++ ret = -EOPNOTSUPP;
++ goto unlock;
++ }
+ /* write one or more registers */
+ reg = msg[0].buf[0];
+ addr = msg[0].addr;
+@@ -431,6 +435,7 @@ static int af9005_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+ ret = 1;
+ }
+
++unlock:
+ mutex_unlock(&d->i2c_mutex);
+ return ret;
+ }
+--
+2.40.1
+
--- /dev/null
+From e05d92e2ef5ac8fa849834545c4eb83dd1824177 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Jul 2023 00:02:20 +0800
+Subject: media: anysee: fix null-ptr-deref in anysee_master_xfer
+
+From: Zhang Shurong <zhang_shurong@foxmail.com>
+
+[ Upstream commit c30411266fd67ea3c02a05c157231654d5a3bdc9 ]
+
+In anysee_master_xfer, msg is controlled by user. When msg[i].buf
+is null and msg[i].len is zero, former checks on msg[i].buf would be
+passed. Malicious data finally reach anysee_master_xfer. If accessing
+msg[i].buf[0] without sanity check, null ptr deref would happen.
+We add check on msg[i].len to prevent crash.
+
+Similar commit:
+commit 0ed554fd769a
+("media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer()")
+
+Signed-off-by: Zhang Shurong <zhang_shurong@foxmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+[hverkuil: add spaces around +]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/dvb-usb-v2/anysee.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/usb/dvb-usb-v2/anysee.c b/drivers/media/usb/dvb-usb-v2/anysee.c
+index aa45b5d263f6b..a1235d0cce92f 100644
+--- a/drivers/media/usb/dvb-usb-v2/anysee.c
++++ b/drivers/media/usb/dvb-usb-v2/anysee.c
+@@ -202,7 +202,7 @@ static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
+
+ while (i < num) {
+ if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
+- if (msg[i].len > 2 || msg[i+1].len > 60) {
++ if (msg[i].len != 2 || msg[i + 1].len > 60) {
+ ret = -EOPNOTSUPP;
+ break;
+ }
+--
+2.40.1
+
--- /dev/null
+From 1379795e86bbccc7dd3d86a024b60bd3f0b914b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Jul 2023 00:28:17 +0800
+Subject: media: az6007: Fix null-ptr-deref in az6007_i2c_xfer()
+
+From: Zhang Shurong <zhang_shurong@foxmail.com>
+
+[ Upstream commit 1047f9343011f2cedc73c64829686206a7e9fc3f ]
+
+In az6007_i2c_xfer, msg is controlled by user. When msg[i].buf
+is null and msg[i].len is zero, former checks on msg[i].buf would be
+passed. Malicious data finally reach az6007_i2c_xfer. If accessing
+msg[i].buf[0] without sanity check, null ptr deref would happen.
+We add check on msg[i].len to prevent crash.
+
+Similar commit:
+commit 0ed554fd769a
+("media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer()")
+
+Signed-off-by: Zhang Shurong <zhang_shurong@foxmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/dvb-usb-v2/az6007.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c
+index 7524c90f5da61..6cbfe75791c21 100644
+--- a/drivers/media/usb/dvb-usb-v2/az6007.c
++++ b/drivers/media/usb/dvb-usb-v2/az6007.c
+@@ -788,6 +788,10 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
+ if (az6007_xfer_debug)
+ printk(KERN_DEBUG "az6007: I2C W addr=0x%x len=%d\n",
+ addr, msgs[i].len);
++ if (msgs[i].len < 1) {
++ ret = -EIO;
++ goto err;
++ }
+ req = AZ6007_I2C_WR;
+ index = msgs[i].buf[0];
+ value = addr | (1 << 8);
+@@ -802,6 +806,10 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
+ if (az6007_xfer_debug)
+ printk(KERN_DEBUG "az6007: I2C R addr=0x%x len=%d\n",
+ addr, msgs[i].len);
++ if (msgs[i].len < 1) {
++ ret = -EIO;
++ goto err;
++ }
+ req = AZ6007_I2C_RD;
+ index = msgs[i].buf[0];
+ value = addr;
+--
+2.40.1
+
--- /dev/null
+From 0fae4e3b5898fb0a53b6f6466dace9b4de3377c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jul 2023 00:06:54 +0800
+Subject: media: dvb-usb-v2: af9035: Fix null-ptr-deref in
+ af9035_i2c_master_xfer
+
+From: Zhang Shurong <zhang_shurong@foxmail.com>
+
+[ Upstream commit 7bf744f2de0a848fb1d717f5831b03db96feae89 ]
+
+In af9035_i2c_master_xfer, msg is controlled by user. When msg[i].buf
+is null and msg[i].len is zero, former checks on msg[i].buf would be
+passed. Malicious data finally reach af9035_i2c_master_xfer. If accessing
+msg[i].buf[0] without sanity check, null ptr deref would happen.
+We add check on msg[i].len to prevent crash.
+
+Similar commit:
+commit 0ed554fd769a
+("media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer()")
+
+Signed-off-by: Zhang Shurong <zhang_shurong@foxmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/dvb-usb-v2/af9035.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
+index 1e9c8d01523be..33a2aa8907e65 100644
+--- a/drivers/media/usb/dvb-usb-v2/af9035.c
++++ b/drivers/media/usb/dvb-usb-v2/af9035.c
+@@ -322,6 +322,8 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
+ ret = -EOPNOTSUPP;
+ } else if ((msg[0].addr == state->af9033_i2c_addr[0]) ||
+ (msg[0].addr == state->af9033_i2c_addr[1])) {
++ if (msg[0].len < 3 || msg[1].len < 1)
++ return -EOPNOTSUPP;
+ /* demod access via firmware interface */
+ u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
+ msg[0].buf[2];
+@@ -381,6 +383,8 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
+ ret = -EOPNOTSUPP;
+ } else if ((msg[0].addr == state->af9033_i2c_addr[0]) ||
+ (msg[0].addr == state->af9033_i2c_addr[1])) {
++ if (msg[0].len < 3)
++ return -EOPNOTSUPP;
+ /* demod access via firmware interface */
+ u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
+ msg[0].buf[2];
+@@ -388,10 +392,7 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
+ if (msg[0].addr == state->af9033_i2c_addr[1])
+ reg |= 0x100000;
+
+- ret = (msg[0].len >= 3) ? af9035_wr_regs(d, reg,
+- &msg[0].buf[3],
+- msg[0].len - 3)
+- : -EOPNOTSUPP;
++ ret = af9035_wr_regs(d, reg, &msg[0].buf[3], msg[0].len - 3);
+ } else {
+ /* I2C write */
+ u8 buf[MAX_XFER_SIZE];
+--
+2.40.1
+
--- /dev/null
+From 52842cbc406b3b0b260db4534ac516e3454dc87a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Jul 2023 13:32:13 +0800
+Subject: media: dvb-usb-v2: gl861: Fix null-ptr-deref in gl861_i2c_master_xfer
+
+From: Zhang Shurong <zhang_shurong@foxmail.com>
+
+[ Upstream commit b97719a66970601cd3151a3e2020f4454a1c4ff6 ]
+
+In gl861_i2c_master_xfer, msg is controlled by user. When msg[i].buf
+is null and msg[i].len is zero, former checks on msg[i].buf would be
+passed. Malicious data finally reach gl861_i2c_master_xfer. If accessing
+msg[i].buf[0] without sanity check, null ptr deref would happen.
+We add check on msg[i].len to prevent crash.
+
+Similar commit:
+commit 0ed554fd769a
+("media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer()")
+
+Signed-off-by: Zhang Shurong <zhang_shurong@foxmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/dvb-usb-v2/gl861.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/usb/dvb-usb-v2/gl861.c b/drivers/media/usb/dvb-usb-v2/gl861.c
+index 0c434259c36f1..c71e7b93476de 100644
+--- a/drivers/media/usb/dvb-usb-v2/gl861.c
++++ b/drivers/media/usb/dvb-usb-v2/gl861.c
+@@ -120,7 +120,7 @@ static int gl861_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+ } else if (num == 2 && !(msg[0].flags & I2C_M_RD) &&
+ (msg[1].flags & I2C_M_RD)) {
+ /* I2C write + read */
+- if (msg[0].len > 1 || msg[1].len > sizeof(ctx->buf)) {
++ if (msg[0].len != 1 || msg[1].len > sizeof(ctx->buf)) {
+ ret = -EOPNOTSUPP;
+ goto err;
+ }
+--
+2.40.1
+
--- /dev/null
+From 72a90b3c0af068b0ac2b28ae8b367e62ddaa9920 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Jul 2023 18:22:52 +0800
+Subject: media: dw2102: Fix null-ptr-deref in dw2102_i2c_transfer()
+
+From: Zhang Shurong <zhang_shurong@foxmail.com>
+
+[ Upstream commit 5ae544d94abc8ff77b1b9bf8774def3fa5689b5b ]
+
+In dw2102_i2c_transfer, msg is controlled by user. When msg[i].buf
+is null and msg[i].len is zero, former checks on msg[i].buf would be
+passed. Malicious data finally reach dw2102_i2c_transfer. If accessing
+msg[i].buf[0] without sanity check, null ptr deref would happen.
+We add check on msg[i].len to prevent crash.
+
+Similar commit:
+commit 950e252cb469
+("[media] dw2102: limit messages to buffer size")
+
+Signed-off-by: Zhang Shurong <zhang_shurong@foxmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/usb/dvb-usb/dw2102.c | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
+index 8747960e61461..356fc728d59a8 100644
+--- a/drivers/media/usb/dvb-usb/dw2102.c
++++ b/drivers/media/usb/dvb-usb/dw2102.c
+@@ -128,6 +128,10 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+
+ switch (num) {
+ case 2:
++ if (msg[0].len < 1) {
++ num = -EOPNOTSUPP;
++ break;
++ }
+ /* read stv0299 register */
+ value = msg[0].buf[0];/* register */
+ for (i = 0; i < msg[1].len; i++) {
+@@ -139,6 +143,10 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+ case 1:
+ switch (msg[0].addr) {
+ case 0x68:
++ if (msg[0].len < 2) {
++ num = -EOPNOTSUPP;
++ break;
++ }
+ /* write to stv0299 register */
+ buf6[0] = 0x2a;
+ buf6[1] = msg[0].buf[0];
+@@ -148,6 +156,10 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+ break;
+ case 0x60:
+ if (msg[0].flags == 0) {
++ if (msg[0].len < 4) {
++ num = -EOPNOTSUPP;
++ break;
++ }
+ /* write to tuner pll */
+ buf6[0] = 0x2c;
+ buf6[1] = 5;
+@@ -159,6 +171,10 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+ dw210x_op_rw(d->udev, 0xb2, 0, 0,
+ buf6, 7, DW210X_WRITE_MSG);
+ } else {
++ if (msg[0].len < 1) {
++ num = -EOPNOTSUPP;
++ break;
++ }
+ /* read from tuner */
+ dw210x_op_rw(d->udev, 0xb5, 0, 0,
+ buf6, 1, DW210X_READ_MSG);
+@@ -166,12 +182,20 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+ }
+ break;
+ case (DW2102_RC_QUERY):
++ if (msg[0].len < 2) {
++ num = -EOPNOTSUPP;
++ break;
++ }
+ dw210x_op_rw(d->udev, 0xb8, 0, 0,
+ buf6, 2, DW210X_READ_MSG);
+ msg[0].buf[0] = buf6[0];
+ msg[0].buf[1] = buf6[1];
+ break;
+ case (DW2102_VOLTAGE_CTRL):
++ if (msg[0].len < 1) {
++ num = -EOPNOTSUPP;
++ break;
++ }
+ buf6[0] = 0x30;
+ buf6[1] = msg[0].buf[0];
+ dw210x_op_rw(d->udev, 0xb2, 0, 0,
+--
+2.40.1
+
--- /dev/null
+From eaff4a78a329bebe1494e92d8a152d7d1b558db3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 May 2023 18:17:18 +0800
+Subject: media: mdp3: Fix resource leaks in of_find_device_by_node
+
+From: Lu Hongfei <luhongfei@vivo.com>
+
+[ Upstream commit 35ca8ce495366909b4c2e701d1356570dd40c4e2 ]
+
+Use put_device to release the object get through of_find_device_by_node,
+avoiding resource leaks.
+
+Signed-off-by: Lu Hongfei <luhongfei@vivo.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c
+index 7bc05f42a23c1..9a3f46c1f6ba3 100644
+--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c
++++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c
+@@ -775,11 +775,13 @@ static int mdp_get_subsys_id(struct device *dev, struct device_node *node,
+ ret = cmdq_dev_get_client_reg(&comp_pdev->dev, &cmdq_reg, index);
+ if (ret != 0) {
+ dev_err(&comp_pdev->dev, "cmdq_dev_get_subsys fail!\n");
++ put_device(&comp_pdev->dev);
+ return -EINVAL;
+ }
+
+ comp->subsys_id = cmdq_reg.subsys;
+ dev_dbg(&comp_pdev->dev, "subsys id=%d\n", cmdq_reg.subsys);
++ put_device(&comp_pdev->dev);
+
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From 8bcbc794e542634d08ce44a69a343e134012c527 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Jul 2023 10:23:42 +0200
+Subject: media: pci: cx23885: replace BUG with error return
+
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+
+[ Upstream commit 2e1796fd4904fdd6062a8e4589778ea899ea0c8d ]
+
+It was completely unnecessary to use BUG in buffer_prepare().
+Just replace it with an error return. This also fixes a smatch warning:
+
+drivers/media/pci/cx23885/cx23885-video.c:422 buffer_prepare() error: uninitialized symbol 'ret'.
+
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/cx23885/cx23885-video.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
+index 671fc0588e431..9af2c5596121c 100644
+--- a/drivers/media/pci/cx23885/cx23885-video.c
++++ b/drivers/media/pci/cx23885/cx23885-video.c
+@@ -413,7 +413,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
+ dev->height >> 1);
+ break;
+ default:
+- BUG();
++ return -EINVAL; /* should not happen */
+ }
+ dprintk(2, "[%p/%d] buffer_init - %dx%d %dbpp 0x%08x - dma=0x%08lx\n",
+ buf, buf->vb.vb2_buf.index,
+--
+2.40.1
+
--- /dev/null
+From 29cd3093eff37284859a338a9ee96b7e54ba5c8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Aug 2023 10:14:30 +0300
+Subject: media: pci: ipu3-cio2: Initialise timing struct to avoid a compiler
+ warning
+
+From: Sakari Ailus <sakari.ailus@linux.intel.com>
+
+[ Upstream commit 9d7531be3085a8f013cf173ccc4e72e3cf493538 ]
+
+Initialise timing struct in cio2_hw_init() to zero in order to avoid a
+compiler warning. The warning was a false positive.
+
+Reported-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
+index 3b76a9d0383a8..1bbe58b24d99d 100644
+--- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
++++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
+@@ -354,7 +354,7 @@ static int cio2_hw_init(struct cio2_device *cio2, struct cio2_queue *q)
+ void __iomem *const base = cio2->base;
+ u8 lanes, csi2bus = q->csi2.port;
+ u8 sensor_vc = SENSOR_VIR_CH_DFLT;
+- struct cio2_csi2_timing timing;
++ struct cio2_csi2_timing timing = { 0 };
+ int i, r;
+
+ fmt = cio2_find_format(NULL, &q->subdev_fmt.code);
+--
+2.40.1
+
--- /dev/null
+From 6323fc3e6d6489013f9bddc070828815e5d1574a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jul 2023 08:20:51 +0200
+Subject: media: tuners: qt1010: replace BUG_ON with a regular error
+
+From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+
+[ Upstream commit ee630b29ea44d1851bb6c903f400956604834463 ]
+
+BUG_ON is unnecessary here, and in addition it confuses smatch.
+Replacing this with an error return help resolve this smatch
+warning:
+
+drivers/media/tuners/qt1010.c:350 qt1010_init() error: buffer overflow 'i2c_data' 34 <= 34
+
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/tuners/qt1010.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/tuners/qt1010.c b/drivers/media/tuners/qt1010.c
+index 60931367b82ca..48fc79cd40273 100644
+--- a/drivers/media/tuners/qt1010.c
++++ b/drivers/media/tuners/qt1010.c
+@@ -345,11 +345,12 @@ static int qt1010_init(struct dvb_frontend *fe)
+ else
+ valptr = &tmpval;
+
+- BUG_ON(i >= ARRAY_SIZE(i2c_data) - 1);
+-
+- err = qt1010_init_meas1(priv, i2c_data[i+1].reg,
+- i2c_data[i].reg,
+- i2c_data[i].val, valptr);
++ if (i >= ARRAY_SIZE(i2c_data) - 1)
++ err = -EIO;
++ else
++ err = qt1010_init_meas1(priv, i2c_data[i + 1].reg,
++ i2c_data[i].reg,
++ i2c_data[i].val, valptr);
+ i++;
+ break;
+ }
+--
+2.40.1
+
--- /dev/null
+From a1af37d72579ea66b3131c151e0f96e968c854fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 16:28:11 +0800
+Subject: MIPS: Use "grep -E" instead of "egrep"
+
+From: Tiezhu Yang <yangtiezhu@loongson.cn>
+
+[ Upstream commit d42f0c6ad502c9f612410e125ebdf290cce8bdc3 ]
+
+The latest version of grep claims the egrep is now obsolete so the build
+now contains warnings that look like:
+ egrep: warning: egrep is obsolescent; using grep -E
+fix this up by moving the related file to use "grep -E" instead.
+
+Here are the steps to install the latest grep:
+
+ wget http://ftp.gnu.org/gnu/grep/grep-3.8.tar.gz
+ tar xf grep-3.8.tar.gz
+ cd grep-3.8 && ./configure && make
+ sudo make install
+ export PATH=/usr/local/bin:$PATH
+
+Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Stable-dep-of: 4fe4a6374c4d ("MIPS: Only fiddle with CHECKFLAGS if `need-compiler'")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/Makefile | 2 +-
+ arch/mips/vdso/Makefile | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/mips/Makefile b/arch/mips/Makefile
+index ee8f47aef98b3..dd6486097e1dc 100644
+--- a/arch/mips/Makefile
++++ b/arch/mips/Makefile
+@@ -352,7 +352,7 @@ KBUILD_LDFLAGS += -m $(ld-emul)
+
+ ifdef need-compiler
+ CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \
+- egrep -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \
++ grep -E -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \
+ sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g')
+ endif
+
+diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
+index f72658b3a53f7..1f7d5c6c10b08 100644
+--- a/arch/mips/vdso/Makefile
++++ b/arch/mips/vdso/Makefile
+@@ -71,7 +71,7 @@ KCOV_INSTRUMENT := n
+
+ # Check that we don't have PIC 'jalr t9' calls left
+ quiet_cmd_vdso_mips_check = VDSOCHK $@
+- cmd_vdso_mips_check = if $(OBJDUMP) --disassemble $@ | egrep -h "jalr.*t9" > /dev/null; \
++ cmd_vdso_mips_check = if $(OBJDUMP) --disassemble $@ | grep -E -h "jalr.*t9" > /dev/null; \
+ then (echo >&2 "$@: PIC 'jalr t9' calls are not supported"; \
+ rm -f $@; /bin/false); fi
+
+--
+2.40.1
+
--- /dev/null
+From 79cd4336559599c64b8386922036f8d5b86573e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Aug 2023 12:56:42 +0100
+Subject: misc: fastrpc: Fix incorrect DMA mapping unmap request
+
+From: Ekansh Gupta <quic_ekangupt@quicinc.com>
+
+[ Upstream commit a2cb9cd6a3949a3804ad9fd7da234892ce6719ec ]
+
+Scatterlist table is obtained during map create request and the same
+table is used for DMA mapping unmap. In case there is any failure
+while getting the sg_table, ERR_PTR is returned instead of sg_table.
+
+When the map is getting freed, there is only a non-NULL check of
+sg_table which will also be true in case failure was returned instead
+of sg_table. This would result in improper unmap request. Add proper
+check before setting map table to avoid bad unmap request.
+
+Fixes: c68cfb718c8f ("misc: fastrpc: Add support for context Invoke method")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Ekansh Gupta <quic_ekangupt@quicinc.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20230811115643.38578-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/fastrpc.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
+index e9291694922bc..4c51d216f3d43 100644
+--- a/drivers/misc/fastrpc.c
++++ b/drivers/misc/fastrpc.c
+@@ -711,6 +711,7 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
+ {
+ struct fastrpc_session_ctx *sess = fl->sctx;
+ struct fastrpc_map *map = NULL;
++ struct sg_table *table;
+ int err = 0;
+
+ if (!fastrpc_map_lookup(fl, fd, ppmap, true))
+@@ -736,11 +737,12 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
+ goto attach_err;
+ }
+
+- map->table = dma_buf_map_attachment_unlocked(map->attach, DMA_BIDIRECTIONAL);
+- if (IS_ERR(map->table)) {
+- err = PTR_ERR(map->table);
++ table = dma_buf_map_attachment_unlocked(map->attach, DMA_BIDIRECTIONAL);
++ if (IS_ERR(table)) {
++ err = PTR_ERR(table);
+ goto map_err;
+ }
++ map->table = table;
+
+ map->phys = sg_dma_address(map->table->sgl);
+ map->phys += ((u64)fl->sctx->sid << 32);
+--
+2.40.1
+
--- /dev/null
+From 6b922ad2da99acccb367205df2880becc98c0da0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Oct 2022 20:22:19 +0300
+Subject: misc: fastrpc: Prepare to dynamic dma-buf locking specification
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+
+[ Upstream commit 791da5c7fedbc1d662445ec030d8f86872f6184c ]
+
+Prepare fastrpc to the common dynamic dma-buf locking convention by
+starting to use the unlocked versions of dma-buf API functions.
+
+Acked-by: Christian König <christian.koenig@amd.com>
+Acked-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20221017172229.42269-12-dmitry.osipenko@collabora.com
+Stable-dep-of: a2cb9cd6a394 ("misc: fastrpc: Fix incorrect DMA mapping unmap request")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/fastrpc.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
+index 13518cac076c7..e9291694922bc 100644
+--- a/drivers/misc/fastrpc.c
++++ b/drivers/misc/fastrpc.c
+@@ -310,8 +310,8 @@ static void fastrpc_free_map(struct kref *ref)
+ return;
+ }
+ }
+- dma_buf_unmap_attachment(map->attach, map->table,
+- DMA_BIDIRECTIONAL);
++ dma_buf_unmap_attachment_unlocked(map->attach, map->table,
++ DMA_BIDIRECTIONAL);
+ dma_buf_detach(map->buf, map->attach);
+ dma_buf_put(map->buf);
+ }
+@@ -736,7 +736,7 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
+ goto attach_err;
+ }
+
+- map->table = dma_buf_map_attachment(map->attach, DMA_BIDIRECTIONAL);
++ map->table = dma_buf_map_attachment_unlocked(map->attach, DMA_BIDIRECTIONAL);
+ if (IS_ERR(map->table)) {
+ err = PTR_ERR(map->table);
+ goto map_err;
+--
+2.40.1
+
--- /dev/null
+From fbe1b9122017503fe8b682ab3f42c33e540f0d6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 21:58:47 +0800
+Subject: misc: open-dice: make OPEN_DICE depend on HAS_IOMEM
+
+From: Baoquan He <bhe@redhat.com>
+
+[ Upstream commit aefc8b57af7787c80686e49a5841e9289cb11f53 ]
+
+On s390 systems (aka mainframes), it has classic channel devices for
+networking and permanent storage that are currently even more common
+than PCI devices. Hence it could have a fully functional s390 kernel
+with CONFIG_PCI=n, then the relevant iomem mapping functions
+[including ioremap(), devm_ioremap(), etc.] are not available.
+
+Here let OPEN_DICE depend on HAS_IOMEM so that it won't be built
+to cause below compiling error if PCI is unset:
+
+------
+ERROR: modpost: "devm_memremap" [drivers/misc/open-dice.ko] undefined!
+ERROR: modpost: "devm_memunmap" [drivers/misc/open-dice.ko] undefined!
+------
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202306211329.ticOJCSv-lkp@intel.com/
+Signed-off-by: Baoquan He <bhe@redhat.com>
+Cc: Derek Kiernan <derek.kiernan@amd.com>
+Cc: Dragan Cvetic <dragan.cvetic@amd.com>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Link: https://lore.kernel.org/r/20230707135852.24292-4-bhe@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
+index 358ad56f65245..0cef98319f0e5 100644
+--- a/drivers/misc/Kconfig
++++ b/drivers/misc/Kconfig
+@@ -474,6 +474,7 @@ config HISI_HIKEY_USB
+ config OPEN_DICE
+ tristate "Open Profile for DICE driver"
+ depends on OF_RESERVED_MEM
++ depends on HAS_IOMEM
+ help
+ This driver exposes a DICE reserved memory region to userspace via
+ a character device. The memory region contains Compound Device
+--
+2.40.1
+
--- /dev/null
+From 086d86e2429ebcb9db8a924a83d77d021f26b4d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Aug 2023 23:48:53 +0200
+Subject: mmc: sdhci-esdhc-imx: improve ESDHC_FLAG_ERR010450
+
+From: Giulio Benetti <giulio.benetti@benettiengineering.com>
+
+[ Upstream commit 5ae4b0d8875caa44946e579420c7fd5740d58653 ]
+
+Errata ERR010450 only shows up if voltage is 1.8V, but if the device is
+supplied by 3v3 the errata can be ignored. So let's check for if quirk
+SDHCI_QUIRK2_NO_1_8_V is defined or not before limiting the frequency.
+
+Cc: Jim Reinhart <jimr@tekvox.com>
+Cc: James Autry <jautry@tekvox.com>
+Cc: Matthew Maron <matthewm@tekvox.com>
+Signed-off-by: Giulio Benetti <giulio.benetti@benettiengineering.com>
+Acked-by: Haibo Chen <haibo.chen@nxp.com>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Link: https://lore.kernel.org/r/20230811214853.8623-1-giulio.benetti@benettiengineering.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/sdhci-esdhc-imx.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
+index b63cf1f9e8fb9..3c7b32c0d3f3f 100644
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -171,8 +171,8 @@
+ #define ESDHC_FLAG_HS400 BIT(9)
+ /*
+ * The IP has errata ERR010450
+- * uSDHC: Due to the I/O timing limit, for SDR mode, SD card clock can't
+- * exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz.
++ * uSDHC: At 1.8V due to the I/O timing limit, for SDR mode, SD card
++ * clock can't exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz.
+ */
+ #define ESDHC_FLAG_ERR010450 BIT(10)
+ /* The IP supports HS400ES mode */
+@@ -932,7 +932,8 @@ static inline void esdhc_pltfm_set_clock(struct sdhci_host *host,
+ | ESDHC_CLOCK_MASK);
+ sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
+
+- if (imx_data->socdata->flags & ESDHC_FLAG_ERR010450) {
++ if ((imx_data->socdata->flags & ESDHC_FLAG_ERR010450) &&
++ (!(host->quirks2 & SDHCI_QUIRK2_NO_1_8_V))) {
+ unsigned int max_clock;
+
+ max_clock = imx_data->is_ddr ? 45000000 : 150000000;
+--
+2.40.1
+
--- /dev/null
+From 873a3fba913ebf7888c131939666d6bec523196e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Apr 2023 15:24:51 -0400
+Subject: mt76: mt7921: don't assume adequate headroom for SDIO headers
+
+From: Matt Whitlock <kernel@mattwhitlock.name>
+
+[ Upstream commit 98c4d0abf5c478db1ad126ff0c187dbb84c0803c ]
+
+mt7921_usb_sdio_tx_prepare_skb() calls mt7921_usb_sdio_write_txwi() and
+mt7921_skb_add_usb_sdio_hdr(), both of which blindly assume that
+adequate headroom will be available in the passed skb. This assumption
+typically is satisfied when the skb was allocated in the net core for
+transmission via the mt7921 netdev (although even that is only an
+optimization and is not strictly guaranteed), but the assumption is
+sometimes not satisfied when the skb originated in the receive path of
+another netdev and was passed through to the mt7921, such as by the
+bridge layer. Blindly prepending bytes to an skb is always wrong.
+
+This commit introduces a call to skb_cow_head() before the call to
+mt7921_usb_sdio_write_txwi() in mt7921_usb_sdio_tx_prepare_skb() to
+ensure that at least MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE bytes can be
+pushed onto the skb.
+
+Without this fix, I can trivially cause kernel panics by bridging an
+MT7921AU-based USB 802.11ax interface with an Ethernet interface on an
+Intel Atom-based x86 system using its onboard RTL8169 PCI Ethernet
+adapter and also on an ARM-based Raspberry Pi 1 using its onboard
+SMSC9512 USB Ethernet adapter. Note that the panics do not occur in
+every system configuration, as they occur only if the receiving netdev
+leaves less headroom in its received skbs than the mt7921 needs for its
+SDIO headers.
+
+Here is an example stack trace of this panic on Raspberry Pi OS Lite
+2023-02-21 running kernel 6.1.24+ [1]:
+
+ skb_panic from skb_push+0x44/0x48
+ skb_push from mt7921_usb_sdio_tx_prepare_skb+0xd4/0x190 [mt7921_common]
+ mt7921_usb_sdio_tx_prepare_skb [mt7921_common] from mt76u_tx_queue_skb+0x94/0x1d0 [mt76_usb]
+ mt76u_tx_queue_skb [mt76_usb] from __mt76_tx_queue_skb+0x4c/0xc8 [mt76]
+ __mt76_tx_queue_skb [mt76] from mt76_txq_schedule.part.0+0x13c/0x398 [mt76]
+ mt76_txq_schedule.part.0 [mt76] from mt76_txq_schedule_all+0x24/0x30 [mt76]
+ mt76_txq_schedule_all [mt76] from mt7921_tx_worker+0x58/0xf4 [mt7921_common]
+ mt7921_tx_worker [mt7921_common] from __mt76_worker_fn+0x9c/0xec [mt76]
+ __mt76_worker_fn [mt76] from kthread+0xbc/0xe0
+ kthread from ret_from_fork+0x14/0x34
+
+After this fix, bridging the mt7921 interface works fine on both of my
+previously problematic systems.
+
+[1] https://github.com/raspberrypi/firmware/tree/5c276f55a4b21345cd4d6200a504ee991851ff7a
+
+Link: https://github.com/openwrt/openwrt/issues/11796
+Signed-off-by: Matt Whitlock <kernel@mattwhitlock.name>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+index 1c0d8cf19b8eb..49ddca84f7862 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+@@ -1167,6 +1167,10 @@ int mt7921_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ if (unlikely(tx_info->skb->len <= ETH_HLEN))
+ return -EINVAL;
+
++ err = skb_cow_head(skb, MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE);
++ if (err)
++ return err;
++
+ if (!wcid)
+ wcid = &dev->mt76.global_wcid;
+
+--
+2.40.1
+
--- /dev/null
+From 44cabbfd5e061057f3e4136b55bdc39f31113c1a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Aug 2023 01:54:08 +0000
+Subject: net/ipv4: return the real errno instead of -EINVAL
+
+From: xu xin <xu.xin16@zte.com.cn>
+
+[ Upstream commit c67180efc507e04a87f22aa68bd7dd832db006b7 ]
+
+For now, No matter what error pointer ip_neigh_for_gw() returns,
+ip_finish_output2() always return -EINVAL, which may mislead the upper
+users.
+
+For exemple, an application uses sendto to send an UDP packet, but when the
+neighbor table overflows, sendto() will get a value of -EINVAL, and it will
+cause users to waste a lot of time checking parameters for errors.
+
+Return the real errno instead of -EINVAL.
+
+Signed-off-by: xu xin <xu.xin16@zte.com.cn>
+Reviewed-by: Yang Yang <yang.yang29@zte.com.cn>
+Cc: Si Hao <si.hao@zte.com.cn>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Link: https://lore.kernel.org/r/20230807015408.248237-1-xu.xin16@zte.com.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_output.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+index ebd2cea5b7d7a..66908ce2dd116 100644
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -234,7 +234,7 @@ static int ip_finish_output2(struct net *net, struct sock *sk, struct sk_buff *s
+ net_dbg_ratelimited("%s: No header cache and no neighbour!\n",
+ __func__);
+ kfree_skb_reason(skb, SKB_DROP_REASON_NEIGH_CREATEFAIL);
+- return -EINVAL;
++ return PTR_ERR(neigh);
+ }
+
+ static int ip_finish_output_gso(struct net *net, struct sock *sk,
+--
+2.40.1
+
--- /dev/null
+From 45eda15dd632bf588a497ade8b7d0112805b5cb1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Jul 2023 17:48:13 -0700
+Subject: net: Use sockaddr_storage for getsockopt(SO_PEERNAME).
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 8936bf53a091ad6a34b480c22002f1cb2422ab38 ]
+
+Commit df8fc4e934c1 ("kbuild: Enable -fstrict-flex-arrays=3") started
+applying strict rules to standard string functions.
+
+It does not work well with conventional socket code around each protocol-
+specific sockaddr_XXX struct, which is cast from sockaddr_storage and has
+a bigger size than fortified functions expect. See these commits:
+
+ commit 06d4c8a80836 ("af_unix: Fix fortify_panic() in unix_bind_bsd().")
+ commit ecb4534b6a1c ("af_unix: Terminate sun_path when bind()ing pathname socket.")
+ commit a0ade8404c3b ("af_packet: Fix warning of fortified memcpy() in packet_getname().")
+
+We must cast the protocol-specific address back to sockaddr_storage
+to call such functions.
+
+However, in the case of getsockaddr(SO_PEERNAME), the rationale is a bit
+unclear as the buffer is defined by char[128] which is the same size as
+sockaddr_storage.
+
+Let's use sockaddr_storage explicitly.
+
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/core/sock.c b/net/core/sock.c
+index e5858fa5d6d57..0ee2e33bbe5f8 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1774,14 +1774,14 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
+
+ case SO_PEERNAME:
+ {
+- char address[128];
++ struct sockaddr_storage address;
+
+- lv = sock->ops->getname(sock, (struct sockaddr *)address, 2);
++ lv = sock->ops->getname(sock, (struct sockaddr *)&address, 2);
+ if (lv < 0)
+ return -ENOTCONN;
+ if (lv < len)
+ return -EINVAL;
+- if (copy_to_sockptr(optval, address, len))
++ if (copy_to_sockptr(optval, &address, len))
+ return -EFAULT;
+ goto lenout;
+ }
+--
+2.40.1
+
--- /dev/null
+From 5c7564c0545400334d50c3d0321995e5a5131973 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 15:45:03 +0800
+Subject: netfilter: ebtables: fix fortify warnings in size_entry_mwt()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: GONG, Ruiqi <gongruiqi1@huawei.com>
+
+[ Upstream commit a7ed3465daa240bdf01a5420f64336fee879c09d ]
+
+When compiling with gcc 13 and CONFIG_FORTIFY_SOURCE=y, the following
+warning appears:
+
+In function ‘fortify_memcpy_chk’,
+ inlined from ‘size_entry_mwt’ at net/bridge/netfilter/ebtables.c:2118:2:
+./include/linux/fortify-string.h:592:25: error: call to ‘__read_overflow2_field’
+declared with attribute warning: detected read beyond size of field (2nd parameter);
+maybe use struct_group()? [-Werror=attribute-warning]
+ 592 | __read_overflow2_field(q_size_field, size);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The compiler is complaining:
+
+memcpy(&offsets[1], &entry->watchers_offset,
+ sizeof(offsets) - sizeof(offsets[0]));
+
+where memcpy reads beyong &entry->watchers_offset to copy
+{watchers,target,next}_offset altogether into offsets[]. Silence the
+warning by wrapping these three up via struct_group().
+
+Signed-off-by: GONG, Ruiqi <gongruiqi1@huawei.com>
+Reviewed-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/uapi/linux/netfilter_bridge/ebtables.h | 14 ++++++++------
+ net/bridge/netfilter/ebtables.c | 3 +--
+ 2 files changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/include/uapi/linux/netfilter_bridge/ebtables.h b/include/uapi/linux/netfilter_bridge/ebtables.h
+index a494cf43a7552..b0caad82b6937 100644
+--- a/include/uapi/linux/netfilter_bridge/ebtables.h
++++ b/include/uapi/linux/netfilter_bridge/ebtables.h
+@@ -182,12 +182,14 @@ struct ebt_entry {
+ unsigned char sourcemsk[ETH_ALEN];
+ unsigned char destmac[ETH_ALEN];
+ unsigned char destmsk[ETH_ALEN];
+- /* sizeof ebt_entry + matches */
+- unsigned int watchers_offset;
+- /* sizeof ebt_entry + matches + watchers */
+- unsigned int target_offset;
+- /* sizeof ebt_entry + matches + watchers + target */
+- unsigned int next_offset;
++ __struct_group(/* no tag */, offsets, /* no attrs */,
++ /* sizeof ebt_entry + matches */
++ unsigned int watchers_offset;
++ /* sizeof ebt_entry + matches + watchers */
++ unsigned int target_offset;
++ /* sizeof ebt_entry + matches + watchers + target */
++ unsigned int next_offset;
++ );
+ unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
+ };
+
+diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
+index 757ec46fc45a0..aa23479b20b2a 100644
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -2115,8 +2115,7 @@ static int size_entry_mwt(const struct ebt_entry *entry, const unsigned char *ba
+ return ret;
+
+ offsets[0] = sizeof(struct ebt_entry); /* matches come first */
+- memcpy(&offsets[1], &entry->watchers_offset,
+- sizeof(offsets) - sizeof(offsets[0]));
++ memcpy(&offsets[1], &entry->offsets, sizeof(entry->offsets));
+
+ if (state->buf_kern_start) {
+ buf_start = state->buf_kern_start + state->buf_kern_offset;
+--
+2.40.1
+
--- /dev/null
+From cb0eb22a987fceee0994a50d1a4d237060c1e422 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 14:54:23 +0200
+Subject: netfilter: nf_tables: adapt set backend to use GC transaction API
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit f6c383b8c31a93752a52697f8430a71dcbc46adf ]
+
+Use the GC transaction API to replace the old and buggy gc API and the
+busy mark approach.
+
+No set elements are removed from async garbage collection anymore,
+instead the _DEAD bit is set on so the set element is not visible from
+lookup path anymore. Async GC enqueues transaction work that might be
+aborted and retried later.
+
+rbtree and pipapo set backends does not set on the _DEAD bit from the
+sync GC path since this runs in control plane path where mutex is held.
+In this case, set elements are deactivated, removed and then released
+via RCU callback, sync GC never fails.
+
+Fixes: 3c4287f62044 ("nf_tables: Add set type for arbitrary concatenation of ranges")
+Fixes: 8d8540c4f5e0 ("netfilter: nft_set_rbtree: add timeout support")
+Fixes: 9d0982927e79 ("netfilter: nft_hash: add support for timeouts")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 7 +-
+ net/netfilter/nft_set_hash.c | 77 +++++++++++-------
+ net/netfilter/nft_set_pipapo.c | 48 ++++++++---
+ net/netfilter/nft_set_rbtree.c | 144 ++++++++++++++++++++-------------
+ 4 files changed, 173 insertions(+), 103 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 4d827177aaebe..35d84e8b79524 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -6148,7 +6148,6 @@ static void nft_setelem_activate(struct net *net, struct nft_set *set,
+
+ if (nft_setelem_is_catchall(set, elem)) {
+ nft_set_elem_change_active(net, set, ext);
+- nft_set_elem_clear_busy(ext);
+ } else {
+ set->ops->activate(net, set, elem);
+ }
+@@ -6163,8 +6162,7 @@ static int nft_setelem_catchall_deactivate(const struct net *net,
+
+ list_for_each_entry(catchall, &set->catchall_list, list) {
+ ext = nft_set_elem_ext(set, catchall->elem);
+- if (!nft_is_active(net, ext) ||
+- nft_set_elem_mark_busy(ext))
++ if (!nft_is_active(net, ext))
+ continue;
+
+ kfree(elem->priv);
+@@ -6874,8 +6872,7 @@ static int nft_set_catchall_flush(const struct nft_ctx *ctx,
+
+ list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
+ ext = nft_set_elem_ext(set, catchall->elem);
+- if (!nft_set_elem_active(ext, genmask) ||
+- nft_set_elem_mark_busy(ext))
++ if (!nft_set_elem_active(ext, genmask))
+ continue;
+
+ elem.priv = catchall->elem;
+diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c
+index 0b73cb0e752f7..960cbd56c0406 100644
+--- a/net/netfilter/nft_set_hash.c
++++ b/net/netfilter/nft_set_hash.c
+@@ -59,6 +59,8 @@ static inline int nft_rhash_cmp(struct rhashtable_compare_arg *arg,
+
+ if (memcmp(nft_set_ext_key(&he->ext), x->key, x->set->klen))
+ return 1;
++ if (nft_set_elem_is_dead(&he->ext))
++ return 1;
+ if (nft_set_elem_expired(&he->ext))
+ return 1;
+ if (!nft_set_elem_active(&he->ext, x->genmask))
+@@ -188,7 +190,6 @@ static void nft_rhash_activate(const struct net *net, const struct nft_set *set,
+ struct nft_rhash_elem *he = elem->priv;
+
+ nft_set_elem_change_active(net, set, &he->ext);
+- nft_set_elem_clear_busy(&he->ext);
+ }
+
+ static bool nft_rhash_flush(const struct net *net,
+@@ -196,12 +197,9 @@ static bool nft_rhash_flush(const struct net *net,
+ {
+ struct nft_rhash_elem *he = priv;
+
+- if (!nft_set_elem_mark_busy(&he->ext) ||
+- !nft_is_active(net, &he->ext)) {
+- nft_set_elem_change_active(net, set, &he->ext);
+- return true;
+- }
+- return false;
++ nft_set_elem_change_active(net, set, &he->ext);
++
++ return true;
+ }
+
+ static void *nft_rhash_deactivate(const struct net *net,
+@@ -218,9 +216,8 @@ static void *nft_rhash_deactivate(const struct net *net,
+
+ rcu_read_lock();
+ he = rhashtable_lookup(&priv->ht, &arg, nft_rhash_params);
+- if (he != NULL &&
+- !nft_rhash_flush(net, set, he))
+- he = NULL;
++ if (he)
++ nft_set_elem_change_active(net, set, &he->ext);
+
+ rcu_read_unlock();
+
+@@ -314,25 +311,48 @@ static bool nft_rhash_expr_needs_gc_run(const struct nft_set *set,
+
+ static void nft_rhash_gc(struct work_struct *work)
+ {
++ struct nftables_pernet *nft_net;
+ struct nft_set *set;
+ struct nft_rhash_elem *he;
+ struct nft_rhash *priv;
+- struct nft_set_gc_batch *gcb = NULL;
+ struct rhashtable_iter hti;
++ struct nft_trans_gc *gc;
++ struct net *net;
++ u32 gc_seq;
+
+ priv = container_of(work, struct nft_rhash, gc_work.work);
+ set = nft_set_container_of(priv);
++ net = read_pnet(&set->net);
++ nft_net = nft_pernet(net);
++ gc_seq = READ_ONCE(nft_net->gc_seq);
++
++ gc = nft_trans_gc_alloc(set, gc_seq, GFP_KERNEL);
++ if (!gc)
++ goto done;
+
+ rhashtable_walk_enter(&priv->ht, &hti);
+ rhashtable_walk_start(&hti);
+
+ while ((he = rhashtable_walk_next(&hti))) {
+ if (IS_ERR(he)) {
+- if (PTR_ERR(he) != -EAGAIN)
+- break;
++ if (PTR_ERR(he) != -EAGAIN) {
++ nft_trans_gc_destroy(gc);
++ gc = NULL;
++ goto try_later;
++ }
+ continue;
+ }
+
++ /* Ruleset has been updated, try later. */
++ if (READ_ONCE(nft_net->gc_seq) != gc_seq) {
++ nft_trans_gc_destroy(gc);
++ gc = NULL;
++ goto try_later;
++ }
++
++ if (nft_set_elem_is_dead(&he->ext))
++ goto dead_elem;
++
+ if (nft_set_ext_exists(&he->ext, NFT_SET_EXT_EXPRESSIONS) &&
+ nft_rhash_expr_needs_gc_run(set, &he->ext))
+ goto needs_gc_run;
+@@ -340,26 +360,26 @@ static void nft_rhash_gc(struct work_struct *work)
+ if (!nft_set_elem_expired(&he->ext))
+ continue;
+ needs_gc_run:
+- if (nft_set_elem_mark_busy(&he->ext))
+- continue;
++ nft_set_elem_dead(&he->ext);
++dead_elem:
++ gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC);
++ if (!gc)
++ goto try_later;
+
+- gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC);
+- if (gcb == NULL)
+- break;
+- rhashtable_remove_fast(&priv->ht, &he->node, nft_rhash_params);
+- atomic_dec(&set->nelems);
+- nft_set_gc_batch_add(gcb, he);
++ nft_trans_gc_elem_add(gc, he);
+ }
++
++ gc = nft_trans_gc_catchall(gc, gc_seq);
++
++try_later:
++ /* catchall list iteration requires rcu read side lock. */
+ rhashtable_walk_stop(&hti);
+ rhashtable_walk_exit(&hti);
+
+- he = nft_set_catchall_gc(set);
+- if (he) {
+- gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC);
+- if (gcb)
+- nft_set_gc_batch_add(gcb, he);
+- }
+- nft_set_gc_batch_complete(gcb);
++ if (gc)
++ nft_trans_gc_queue_async_done(gc);
++
++done:
+ queue_delayed_work(system_power_efficient_wq, &priv->gc_work,
+ nft_set_gc_interval(set));
+ }
+@@ -422,7 +442,6 @@ static void nft_rhash_destroy(const struct nft_ctx *ctx,
+ };
+
+ cancel_delayed_work_sync(&priv->gc_work);
+- rcu_barrier();
+ rhashtable_free_and_destroy(&priv->ht, nft_rhash_elem_destroy,
+ (void *)&rhash_ctx);
+ }
+diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
+index 8c16681884b7e..0a49c59a22dbd 100644
+--- a/net/netfilter/nft_set_pipapo.c
++++ b/net/netfilter/nft_set_pipapo.c
+@@ -1536,16 +1536,34 @@ static void pipapo_drop(struct nft_pipapo_match *m,
+ }
+ }
+
++static void nft_pipapo_gc_deactivate(struct net *net, struct nft_set *set,
++ struct nft_pipapo_elem *e)
++
++{
++ struct nft_set_elem elem = {
++ .priv = e,
++ };
++
++ nft_setelem_data_deactivate(net, set, &elem);
++}
++
+ /**
+ * pipapo_gc() - Drop expired entries from set, destroy start and end elements
+ * @set: nftables API set representation
+ * @m: Matching data
+ */
+-static void pipapo_gc(const struct nft_set *set, struct nft_pipapo_match *m)
++static void pipapo_gc(const struct nft_set *_set, struct nft_pipapo_match *m)
+ {
++ struct nft_set *set = (struct nft_set *) _set;
+ struct nft_pipapo *priv = nft_set_priv(set);
++ struct net *net = read_pnet(&set->net);
+ int rules_f0, first_rule = 0;
+ struct nft_pipapo_elem *e;
++ struct nft_trans_gc *gc;
++
++ gc = nft_trans_gc_alloc(set, 0, GFP_KERNEL);
++ if (!gc)
++ return;
+
+ while ((rules_f0 = pipapo_rules_same_key(m->f, first_rule))) {
+ union nft_pipapo_map_bucket rulemap[NFT_PIPAPO_MAX_FIELDS];
+@@ -1569,13 +1587,20 @@ static void pipapo_gc(const struct nft_set *set, struct nft_pipapo_match *m)
+ f--;
+ i--;
+ e = f->mt[rulemap[i].to].e;
+- if (nft_set_elem_expired(&e->ext) &&
+- !nft_set_elem_mark_busy(&e->ext)) {
++
++ /* synchronous gc never fails, there is no need to set on
++ * NFT_SET_ELEM_DEAD_BIT.
++ */
++ if (nft_set_elem_expired(&e->ext)) {
+ priv->dirty = true;
+- pipapo_drop(m, rulemap);
+
+- rcu_barrier();
+- nft_set_elem_destroy(set, e, true);
++ gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC);
++ if (!gc)
++ break;
++
++ nft_pipapo_gc_deactivate(net, set, e);
++ pipapo_drop(m, rulemap);
++ nft_trans_gc_elem_add(gc, e);
+
+ /* And check again current first rule, which is now the
+ * first we haven't checked.
+@@ -1585,11 +1610,11 @@ static void pipapo_gc(const struct nft_set *set, struct nft_pipapo_match *m)
+ }
+ }
+
+- e = nft_set_catchall_gc(set);
+- if (e)
+- nft_set_elem_destroy(set, e, true);
+-
+- priv->last_gc = jiffies;
++ gc = nft_trans_gc_catchall(gc, 0);
++ if (gc) {
++ nft_trans_gc_queue_sync_done(gc);
++ priv->last_gc = jiffies;
++ }
+ }
+
+ /**
+@@ -1725,7 +1750,6 @@ static void nft_pipapo_activate(const struct net *net,
+ return;
+
+ nft_set_elem_change_active(net, set, &e->ext);
+- nft_set_elem_clear_busy(&e->ext);
+ }
+
+ /**
+diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c
+index 8d73fffd2d09d..7015153b7be18 100644
+--- a/net/netfilter/nft_set_rbtree.c
++++ b/net/netfilter/nft_set_rbtree.c
+@@ -46,6 +46,12 @@ static int nft_rbtree_cmp(const struct nft_set *set,
+ set->klen);
+ }
+
++static bool nft_rbtree_elem_expired(const struct nft_rbtree_elem *rbe)
++{
++ return nft_set_elem_expired(&rbe->ext) ||
++ nft_set_elem_is_dead(&rbe->ext);
++}
++
+ static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set,
+ const u32 *key, const struct nft_set_ext **ext,
+ unsigned int seq)
+@@ -80,7 +86,7 @@ static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set
+ continue;
+ }
+
+- if (nft_set_elem_expired(&rbe->ext))
++ if (nft_rbtree_elem_expired(rbe))
+ return false;
+
+ if (nft_rbtree_interval_end(rbe)) {
+@@ -98,7 +104,7 @@ static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set
+
+ if (set->flags & NFT_SET_INTERVAL && interval != NULL &&
+ nft_set_elem_active(&interval->ext, genmask) &&
+- !nft_set_elem_expired(&interval->ext) &&
++ !nft_rbtree_elem_expired(interval) &&
+ nft_rbtree_interval_start(interval)) {
+ *ext = &interval->ext;
+ return true;
+@@ -215,6 +221,18 @@ static void *nft_rbtree_get(const struct net *net, const struct nft_set *set,
+ return rbe;
+ }
+
++static void nft_rbtree_gc_remove(struct net *net, struct nft_set *set,
++ struct nft_rbtree *priv,
++ struct nft_rbtree_elem *rbe)
++{
++ struct nft_set_elem elem = {
++ .priv = rbe,
++ };
++
++ nft_setelem_data_deactivate(net, set, &elem);
++ rb_erase(&rbe->node, &priv->root);
++}
++
+ static int nft_rbtree_gc_elem(const struct nft_set *__set,
+ struct nft_rbtree *priv,
+ struct nft_rbtree_elem *rbe,
+@@ -222,11 +240,12 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set,
+ {
+ struct nft_set *set = (struct nft_set *)__set;
+ struct rb_node *prev = rb_prev(&rbe->node);
++ struct net *net = read_pnet(&set->net);
+ struct nft_rbtree_elem *rbe_prev;
+- struct nft_set_gc_batch *gcb;
++ struct nft_trans_gc *gc;
+
+- gcb = nft_set_gc_batch_check(set, NULL, GFP_ATOMIC);
+- if (!gcb)
++ gc = nft_trans_gc_alloc(set, 0, GFP_ATOMIC);
++ if (!gc)
+ return -ENOMEM;
+
+ /* search for end interval coming before this element.
+@@ -244,17 +263,28 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set,
+
+ if (prev) {
+ rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node);
++ nft_rbtree_gc_remove(net, set, priv, rbe_prev);
+
+- rb_erase(&rbe_prev->node, &priv->root);
+- atomic_dec(&set->nelems);
+- nft_set_gc_batch_add(gcb, rbe_prev);
++ /* There is always room in this trans gc for this element,
++ * memory allocation never actually happens, hence, the warning
++ * splat in such case. No need to set NFT_SET_ELEM_DEAD_BIT,
++ * this is synchronous gc which never fails.
++ */
++ gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC);
++ if (WARN_ON_ONCE(!gc))
++ return -ENOMEM;
++
++ nft_trans_gc_elem_add(gc, rbe_prev);
+ }
+
+- rb_erase(&rbe->node, &priv->root);
+- atomic_dec(&set->nelems);
++ nft_rbtree_gc_remove(net, set, priv, rbe);
++ gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC);
++ if (WARN_ON_ONCE(!gc))
++ return -ENOMEM;
++
++ nft_trans_gc_elem_add(gc, rbe);
+
+- nft_set_gc_batch_add(gcb, rbe);
+- nft_set_gc_batch_complete(gcb);
++ nft_trans_gc_queue_sync_done(gc);
+
+ return 0;
+ }
+@@ -482,7 +512,6 @@ static void nft_rbtree_activate(const struct net *net,
+ struct nft_rbtree_elem *rbe = elem->priv;
+
+ nft_set_elem_change_active(net, set, &rbe->ext);
+- nft_set_elem_clear_busy(&rbe->ext);
+ }
+
+ static bool nft_rbtree_flush(const struct net *net,
+@@ -490,12 +519,9 @@ static bool nft_rbtree_flush(const struct net *net,
+ {
+ struct nft_rbtree_elem *rbe = priv;
+
+- if (!nft_set_elem_mark_busy(&rbe->ext) ||
+- !nft_is_active(net, &rbe->ext)) {
+- nft_set_elem_change_active(net, set, &rbe->ext);
+- return true;
+- }
+- return false;
++ nft_set_elem_change_active(net, set, &rbe->ext);
++
++ return true;
+ }
+
+ static void *nft_rbtree_deactivate(const struct net *net,
+@@ -572,26 +598,40 @@ static void nft_rbtree_walk(const struct nft_ctx *ctx,
+
+ static void nft_rbtree_gc(struct work_struct *work)
+ {
+- struct nft_rbtree_elem *rbe, *rbe_end = NULL, *rbe_prev = NULL;
+- struct nft_set_gc_batch *gcb = NULL;
++ struct nft_rbtree_elem *rbe, *rbe_end = NULL;
++ struct nftables_pernet *nft_net;
+ struct nft_rbtree *priv;
++ struct nft_trans_gc *gc;
+ struct rb_node *node;
+ struct nft_set *set;
++ unsigned int gc_seq;
+ struct net *net;
+- u8 genmask;
+
+ priv = container_of(work, struct nft_rbtree, gc_work.work);
+ set = nft_set_container_of(priv);
+ net = read_pnet(&set->net);
+- genmask = nft_genmask_cur(net);
++ nft_net = nft_pernet(net);
++ gc_seq = READ_ONCE(nft_net->gc_seq);
++
++ gc = nft_trans_gc_alloc(set, gc_seq, GFP_KERNEL);
++ if (!gc)
++ goto done;
+
+ write_lock_bh(&priv->lock);
+ write_seqcount_begin(&priv->count);
+ for (node = rb_first(&priv->root); node != NULL; node = rb_next(node)) {
++
++ /* Ruleset has been updated, try later. */
++ if (READ_ONCE(nft_net->gc_seq) != gc_seq) {
++ nft_trans_gc_destroy(gc);
++ gc = NULL;
++ goto try_later;
++ }
++
+ rbe = rb_entry(node, struct nft_rbtree_elem, node);
+
+- if (!nft_set_elem_active(&rbe->ext, genmask))
+- continue;
++ if (nft_set_elem_is_dead(&rbe->ext))
++ goto dead_elem;
+
+ /* elements are reversed in the rbtree for historical reasons,
+ * from highest to lowest value, that is why end element is
+@@ -604,46 +644,36 @@ static void nft_rbtree_gc(struct work_struct *work)
+ if (!nft_set_elem_expired(&rbe->ext))
+ continue;
+
+- if (nft_set_elem_mark_busy(&rbe->ext)) {
+- rbe_end = NULL;
++ nft_set_elem_dead(&rbe->ext);
++
++ if (!rbe_end)
+ continue;
+- }
+
+- if (rbe_prev) {
+- rb_erase(&rbe_prev->node, &priv->root);
+- rbe_prev = NULL;
+- }
+- gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC);
+- if (!gcb)
+- break;
++ nft_set_elem_dead(&rbe_end->ext);
+
+- atomic_dec(&set->nelems);
+- nft_set_gc_batch_add(gcb, rbe);
+- rbe_prev = rbe;
++ gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC);
++ if (!gc)
++ goto try_later;
+
+- if (rbe_end) {
+- atomic_dec(&set->nelems);
+- nft_set_gc_batch_add(gcb, rbe_end);
+- rb_erase(&rbe_end->node, &priv->root);
+- rbe_end = NULL;
+- }
+- node = rb_next(node);
+- if (!node)
+- break;
++ nft_trans_gc_elem_add(gc, rbe_end);
++ rbe_end = NULL;
++dead_elem:
++ gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC);
++ if (!gc)
++ goto try_later;
++
++ nft_trans_gc_elem_add(gc, rbe);
+ }
+- if (rbe_prev)
+- rb_erase(&rbe_prev->node, &priv->root);
++
++ gc = nft_trans_gc_catchall(gc, gc_seq);
++
++try_later:
+ write_seqcount_end(&priv->count);
+ write_unlock_bh(&priv->lock);
+
+- rbe = nft_set_catchall_gc(set);
+- if (rbe) {
+- gcb = nft_set_gc_batch_check(set, gcb, GFP_ATOMIC);
+- if (gcb)
+- nft_set_gc_batch_add(gcb, rbe);
+- }
+- nft_set_gc_batch_complete(gcb);
+-
++ if (gc)
++ nft_trans_gc_queue_async_done(gc);
++done:
+ queue_delayed_work(system_power_efficient_wq, &priv->gc_work,
+ nft_set_gc_interval(set));
+ }
+--
+2.40.1
+
--- /dev/null
+From ab4d2fdc1d651fc87fbeec81aa3d9172e5d04851 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Aug 2023 15:39:00 +0200
+Subject: netfilter: nf_tables: fix GC transaction races with netns and netlink
+ event exit path
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 6a33d8b73dfac0a41f3877894b38082bd0c9a5bc ]
+
+Netlink event path is missing a synchronization point with GC
+transactions. Add GC sequence number update to netns release path and
+netlink event path, any GC transaction losing race will be discarded.
+
+Fixes: 5f68718b34a5 ("netfilter: nf_tables: GC transaction API to avoid race with control plane")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 36 +++++++++++++++++++++++++++++++----
+ 1 file changed, 32 insertions(+), 4 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 2f8290e175ad7..c0f1eccf2283d 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -9408,6 +9408,22 @@ static void nft_set_commit_update(struct list_head *set_update_list)
+ }
+ }
+
++static unsigned int nft_gc_seq_begin(struct nftables_pernet *nft_net)
++{
++ unsigned int gc_seq;
++
++ /* Bump gc counter, it becomes odd, this is the busy mark. */
++ gc_seq = READ_ONCE(nft_net->gc_seq);
++ WRITE_ONCE(nft_net->gc_seq, ++gc_seq);
++
++ return gc_seq;
++}
++
++static void nft_gc_seq_end(struct nftables_pernet *nft_net, unsigned int gc_seq)
++{
++ WRITE_ONCE(nft_net->gc_seq, ++gc_seq);
++}
++
+ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
+ {
+ struct nftables_pernet *nft_net = nft_pernet(net);
+@@ -9493,9 +9509,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
+
+ WRITE_ONCE(nft_net->base_seq, base_seq);
+
+- /* Bump gc counter, it becomes odd, this is the busy mark. */
+- gc_seq = READ_ONCE(nft_net->gc_seq);
+- WRITE_ONCE(nft_net->gc_seq, ++gc_seq);
++ gc_seq = nft_gc_seq_begin(nft_net);
+
+ /* step 3. Start new generation, rules_gen_X now in use. */
+ net->nft.gencursor = nft_gencursor_next(net);
+@@ -9686,7 +9700,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
+ nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN);
+ nf_tables_commit_audit_log(&adl, nft_net->base_seq);
+
+- WRITE_ONCE(nft_net->gc_seq, ++gc_seq);
++ nft_gc_seq_end(nft_net, gc_seq);
+ nf_tables_commit_release(net);
+
+ return 0;
+@@ -10669,6 +10683,7 @@ static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event,
+ struct net *net = n->net;
+ unsigned int deleted;
+ bool restart = false;
++ unsigned int gc_seq;
+
+ if (event != NETLINK_URELEASE || n->protocol != NETLINK_NETFILTER)
+ return NOTIFY_DONE;
+@@ -10676,6 +10691,9 @@ static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event,
+ nft_net = nft_pernet(net);
+ deleted = 0;
+ mutex_lock(&nft_net->commit_mutex);
++
++ gc_seq = nft_gc_seq_begin(nft_net);
++
+ if (!list_empty(&nf_tables_destroy_list))
+ nf_tables_trans_destroy_flush_work();
+ again:
+@@ -10698,6 +10716,8 @@ static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event,
+ if (restart)
+ goto again;
+ }
++ nft_gc_seq_end(nft_net, gc_seq);
++
+ mutex_unlock(&nft_net->commit_mutex);
+
+ return NOTIFY_DONE;
+@@ -10735,12 +10755,20 @@ static void __net_exit nf_tables_pre_exit_net(struct net *net)
+ static void __net_exit nf_tables_exit_net(struct net *net)
+ {
+ struct nftables_pernet *nft_net = nft_pernet(net);
++ unsigned int gc_seq;
+
+ mutex_lock(&nft_net->commit_mutex);
++
++ gc_seq = nft_gc_seq_begin(nft_net);
++
+ if (!list_empty(&nft_net->commit_list) ||
+ !list_empty(&nft_net->module_list))
+ __nf_tables_abort(net, NFNL_ABORT_NONE);
++
+ __nft_release_tables(net);
++
++ nft_gc_seq_end(nft_net, gc_seq);
++
+ mutex_unlock(&nft_net->commit_mutex);
+ WARN_ON_ONCE(!list_empty(&nft_net->tables));
+ WARN_ON_ONCE(!list_empty(&nft_net->module_list));
+--
+2.40.1
+
--- /dev/null
+From d5ae1c479fa44a220754d6d7a512b8a44d71feea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Aug 2023 23:59:03 +0200
+Subject: netfilter: nf_tables: fix kdoc warnings after gc rework
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 08713cb006b6f07434f276c5ee214fb20c7fd965 ]
+
+Jakub Kicinski says:
+ We've got some new kdoc warnings here:
+ net/netfilter/nft_set_pipapo.c:1557: warning: Function parameter or member '_set' not described in 'pipapo_gc'
+ net/netfilter/nft_set_pipapo.c:1557: warning: Excess function parameter 'set' description in 'pipapo_gc'
+ include/net/netfilter/nf_tables.h:577: warning: Function parameter or member 'dead' not described in 'nft_set'
+
+Fixes: 5f68718b34a5 ("netfilter: nf_tables: GC transaction API to avoid race with control plane")
+Fixes: f6c383b8c31a ("netfilter: nf_tables: adapt set backend to use GC transaction API")
+Reported-by: Jakub Kicinski <kuba@kernel.org>
+Closes: https://lore.kernel.org/netdev/20230810104638.746e46f1@kernel.org/
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netfilter/nf_tables.h | 1 +
+ net/netfilter/nft_set_pipapo.c | 2 +-
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
+index 143c6db05be52..31b22c541cf22 100644
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -529,6 +529,7 @@ struct nft_set_elem_expr {
+ * @expr: stateful expression
+ * @ops: set ops
+ * @flags: set flags
++ * @dead: set will be freed, never cleared
+ * @genmask: generation mask
+ * @klen: key length
+ * @dlen: data length
+diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
+index 0a49c59a22dbd..03472c1d9d548 100644
+--- a/net/netfilter/nft_set_pipapo.c
++++ b/net/netfilter/nft_set_pipapo.c
+@@ -1549,7 +1549,7 @@ static void nft_pipapo_gc_deactivate(struct net *net, struct nft_set *set,
+
+ /**
+ * pipapo_gc() - Drop expired entries from set, destroy start and end elements
+- * @set: nftables API set representation
++ * @_set: nftables API set representation
+ * @m: Matching data
+ */
+ static void pipapo_gc(const struct nft_set *_set, struct nft_pipapo_match *m)
+--
+2.40.1
+
--- /dev/null
+From 4f598f962a1ca0d5412f5e14001b99b0adb43bcc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 14:31:54 +0200
+Subject: netfilter: nf_tables: GC transaction API to avoid race with control
+ plane
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 5f68718b34a531a556f2f50300ead2862278da26 ]
+
+The set types rhashtable and rbtree use a GC worker to reclaim memory.
+From system work queue, in periodic intervals, a scan of the table is
+done.
+
+The major caveat here is that the nft transaction mutex is not held.
+This causes a race between control plane and GC when they attempt to
+delete the same element.
+
+We cannot grab the netlink mutex from the work queue, because the
+control plane has to wait for the GC work queue in case the set is to be
+removed, so we get following deadlock:
+
+ cpu 1 cpu2
+ GC work transaction comes in , lock nft mutex
+ `acquire nft mutex // BLOCKS
+ transaction asks to remove the set
+ set destruction calls cancel_work_sync()
+
+cancel_work_sync will now block forever, because it is waiting for the
+mutex the caller already owns.
+
+This patch adds a new API that deals with garbage collection in two
+steps:
+
+1) Lockless GC of expired elements sets on the NFT_SET_ELEM_DEAD_BIT
+ so they are not visible via lookup. Annotate current GC sequence in
+ the GC transaction. Enqueue GC transaction work as soon as it is
+ full. If ruleset is updated, then GC transaction is aborted and
+ retried later.
+
+2) GC work grabs the mutex. If GC sequence has changed then this GC
+ transaction lost race with control plane, abort it as it contains
+ stale references to objects and let GC try again later. If the
+ ruleset is intact, then this GC transaction deactivates and removes
+ the elements and it uses call_rcu() to destroy elements.
+
+Note that no elements are removed from GC lockless path, the _DEAD bit
+is set and pointers are collected. GC catchall does not remove the
+elements anymore too. There is a new set->dead flag that is set on to
+abort the GC transaction to deal with set->ops->destroy() path which
+removes the remaining elements in the set from commit_release, where no
+mutex is held.
+
+To deal with GC when mutex is held, which allows safe deactivate and
+removal, add sync GC API which releases the set element object via
+call_rcu(). This is used by rbtree and pipapo backends which also
+perform garbage collection from control plane path.
+
+Since element removal from sets can happen from control plane and
+element garbage collection/timeout, it is necessary to keep the set
+structure alive until all elements have been deactivated and destroyed.
+
+We cannot do a cancel_work_sync or flush_work in nft_set_destroy because
+its called with the transaction mutex held, but the aforementioned async
+work queue might be blocked on the very mutex that nft_set_destroy()
+callchain is sitting on.
+
+This gives us the choice of ABBA deadlock or UaF.
+
+To avoid both, add set->refs refcount_t member. The GC API can then
+increment the set refcount and release it once the elements have been
+free'd.
+
+Set backends are adapted to use the GC transaction API in a follow up
+patch entitled:
+
+ ("netfilter: nf_tables: use gc transaction API in set backends")
+
+This is joint work with Florian Westphal.
+
+Fixes: cfed7e1b1f8e ("netfilter: nf_tables: add set garbage collection helpers")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netfilter/nf_tables.h | 64 +++++++-
+ net/netfilter/nf_tables_api.c | 248 ++++++++++++++++++++++++++++--
+ 2 files changed, 300 insertions(+), 12 deletions(-)
+
+diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
+index 120be22ef6aa2..483b106466f3d 100644
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -507,6 +507,7 @@ struct nft_set_elem_expr {
+ *
+ * @list: table set list node
+ * @bindings: list of set bindings
++ * @refs: internal refcounting for async set destruction
+ * @table: table this set belongs to
+ * @net: netnamespace this set belongs to
+ * @name: name of the set
+@@ -536,6 +537,7 @@ struct nft_set_elem_expr {
+ struct nft_set {
+ struct list_head list;
+ struct list_head bindings;
++ refcount_t refs;
+ struct nft_table *table;
+ possible_net_t net;
+ char *name;
+@@ -557,7 +559,8 @@ struct nft_set {
+ struct list_head pending_update;
+ /* runtime data below here */
+ const struct nft_set_ops *ops ____cacheline_aligned;
+- u16 flags:14,
++ u16 flags:13,
++ dead:1,
+ genmask:2;
+ u8 klen;
+ u8 dlen;
+@@ -1579,6 +1582,32 @@ static inline void nft_set_elem_clear_busy(struct nft_set_ext *ext)
+ clear_bit(NFT_SET_ELEM_BUSY_BIT, word);
+ }
+
++#define NFT_SET_ELEM_DEAD_MASK (1 << 3)
++
++#if defined(__LITTLE_ENDIAN_BITFIELD)
++#define NFT_SET_ELEM_DEAD_BIT 3
++#elif defined(__BIG_ENDIAN_BITFIELD)
++#define NFT_SET_ELEM_DEAD_BIT (BITS_PER_LONG - BITS_PER_BYTE + 3)
++#else
++#error
++#endif
++
++static inline void nft_set_elem_dead(struct nft_set_ext *ext)
++{
++ unsigned long *word = (unsigned long *)ext;
++
++ BUILD_BUG_ON(offsetof(struct nft_set_ext, genmask) != 0);
++ set_bit(NFT_SET_ELEM_DEAD_BIT, word);
++}
++
++static inline int nft_set_elem_is_dead(const struct nft_set_ext *ext)
++{
++ unsigned long *word = (unsigned long *)ext;
++
++ BUILD_BUG_ON(offsetof(struct nft_set_ext, genmask) != 0);
++ return test_bit(NFT_SET_ELEM_DEAD_BIT, word);
++}
++
+ /**
+ * struct nft_trans - nf_tables object update in transaction
+ *
+@@ -1710,6 +1739,38 @@ struct nft_trans_flowtable {
+ #define nft_trans_flowtable_flags(trans) \
+ (((struct nft_trans_flowtable *)trans->data)->flags)
+
++#define NFT_TRANS_GC_BATCHCOUNT 256
++
++struct nft_trans_gc {
++ struct list_head list;
++ struct net *net;
++ struct nft_set *set;
++ u32 seq;
++ u8 count;
++ void *priv[NFT_TRANS_GC_BATCHCOUNT];
++ struct rcu_head rcu;
++};
++
++struct nft_trans_gc *nft_trans_gc_alloc(struct nft_set *set,
++ unsigned int gc_seq, gfp_t gfp);
++void nft_trans_gc_destroy(struct nft_trans_gc *trans);
++
++struct nft_trans_gc *nft_trans_gc_queue_async(struct nft_trans_gc *gc,
++ unsigned int gc_seq, gfp_t gfp);
++void nft_trans_gc_queue_async_done(struct nft_trans_gc *gc);
++
++struct nft_trans_gc *nft_trans_gc_queue_sync(struct nft_trans_gc *gc, gfp_t gfp);
++void nft_trans_gc_queue_sync_done(struct nft_trans_gc *trans);
++
++void nft_trans_gc_elem_add(struct nft_trans_gc *gc, void *priv);
++
++struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc,
++ unsigned int gc_seq);
++
++void nft_setelem_data_deactivate(const struct net *net,
++ const struct nft_set *set,
++ struct nft_set_elem *elem);
++
+ int __init nft_chain_filter_init(void);
+ void nft_chain_filter_fini(void);
+
+@@ -1736,6 +1797,7 @@ struct nftables_pernet {
+ struct mutex commit_mutex;
+ u64 table_handle;
+ unsigned int base_seq;
++ unsigned int gc_seq;
+ };
+
+ extern unsigned int nf_tables_net_id;
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index a013d2a31f0b8..4d827177aaebe 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -31,7 +31,9 @@ static LIST_HEAD(nf_tables_expressions);
+ static LIST_HEAD(nf_tables_objects);
+ static LIST_HEAD(nf_tables_flowtables);
+ static LIST_HEAD(nf_tables_destroy_list);
++static LIST_HEAD(nf_tables_gc_list);
+ static DEFINE_SPINLOCK(nf_tables_destroy_list_lock);
++static DEFINE_SPINLOCK(nf_tables_gc_list_lock);
+
+ enum {
+ NFT_VALIDATE_SKIP = 0,
+@@ -120,6 +122,9 @@ static void nft_validate_state_update(struct nft_table *table, u8 new_validate_s
+ static void nf_tables_trans_destroy_work(struct work_struct *w);
+ static DECLARE_WORK(trans_destroy_work, nf_tables_trans_destroy_work);
+
++static void nft_trans_gc_work(struct work_struct *work);
++static DECLARE_WORK(trans_gc_work, nft_trans_gc_work);
++
+ static void nft_ctx_init(struct nft_ctx *ctx,
+ struct net *net,
+ const struct sk_buff *skb,
+@@ -581,10 +586,6 @@ static int nft_trans_set_add(const struct nft_ctx *ctx, int msg_type,
+ return __nft_trans_set_add(ctx, msg_type, set, NULL);
+ }
+
+-static void nft_setelem_data_deactivate(const struct net *net,
+- const struct nft_set *set,
+- struct nft_set_elem *elem);
+-
+ static int nft_mapelem_deactivate(const struct nft_ctx *ctx,
+ struct nft_set *set,
+ const struct nft_set_iter *iter,
+@@ -4853,6 +4854,7 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+
+ INIT_LIST_HEAD(&set->bindings);
+ INIT_LIST_HEAD(&set->catchall_list);
++ refcount_set(&set->refs, 1);
+ set->table = table;
+ write_pnet(&set->net, net);
+ set->ops = ops;
+@@ -4920,6 +4922,14 @@ static void nft_set_catchall_destroy(const struct nft_ctx *ctx,
+ }
+ }
+
++static void nft_set_put(struct nft_set *set)
++{
++ if (refcount_dec_and_test(&set->refs)) {
++ kfree(set->name);
++ kvfree(set);
++ }
++}
++
+ static void nft_set_destroy(const struct nft_ctx *ctx, struct nft_set *set)
+ {
+ int i;
+@@ -4932,8 +4942,7 @@ static void nft_set_destroy(const struct nft_ctx *ctx, struct nft_set *set)
+
+ set->ops->destroy(ctx, set);
+ nft_set_catchall_destroy(ctx, set);
+- kfree(set->name);
+- kvfree(set);
++ nft_set_put(set);
+ }
+
+ static int nf_tables_delset(struct sk_buff *skb, const struct nfnl_info *info,
+@@ -6046,7 +6055,8 @@ struct nft_set_ext *nft_set_catchall_lookup(const struct net *net,
+ list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
+ ext = nft_set_elem_ext(set, catchall->elem);
+ if (nft_set_elem_active(ext, genmask) &&
+- !nft_set_elem_expired(ext))
++ !nft_set_elem_expired(ext) &&
++ !nft_set_elem_is_dead(ext))
+ return ext;
+ }
+
+@@ -6698,9 +6708,9 @@ static void nft_setelem_data_activate(const struct net *net,
+ nft_use_inc_restore(&(*nft_set_ext_obj(ext))->use);
+ }
+
+-static void nft_setelem_data_deactivate(const struct net *net,
+- const struct nft_set *set,
+- struct nft_set_elem *elem)
++void nft_setelem_data_deactivate(const struct net *net,
++ const struct nft_set *set,
++ struct nft_set_elem *elem)
+ {
+ const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
+
+@@ -9088,6 +9098,207 @@ void nft_chain_del(struct nft_chain *chain)
+ list_del_rcu(&chain->list);
+ }
+
++static void nft_trans_gc_setelem_remove(struct nft_ctx *ctx,
++ struct nft_trans_gc *trans)
++{
++ void **priv = trans->priv;
++ unsigned int i;
++
++ for (i = 0; i < trans->count; i++) {
++ struct nft_set_elem elem = {
++ .priv = priv[i],
++ };
++
++ nft_setelem_data_deactivate(ctx->net, trans->set, &elem);
++ nft_setelem_remove(ctx->net, trans->set, &elem);
++ }
++}
++
++void nft_trans_gc_destroy(struct nft_trans_gc *trans)
++{
++ nft_set_put(trans->set);
++ put_net(trans->net);
++ kfree(trans);
++}
++
++static void nft_trans_gc_trans_free(struct rcu_head *rcu)
++{
++ struct nft_set_elem elem = {};
++ struct nft_trans_gc *trans;
++ struct nft_ctx ctx = {};
++ unsigned int i;
++
++ trans = container_of(rcu, struct nft_trans_gc, rcu);
++ ctx.net = read_pnet(&trans->set->net);
++
++ for (i = 0; i < trans->count; i++) {
++ elem.priv = trans->priv[i];
++ if (!nft_setelem_is_catchall(trans->set, &elem))
++ atomic_dec(&trans->set->nelems);
++
++ nf_tables_set_elem_destroy(&ctx, trans->set, elem.priv);
++ }
++
++ nft_trans_gc_destroy(trans);
++}
++
++static bool nft_trans_gc_work_done(struct nft_trans_gc *trans)
++{
++ struct nftables_pernet *nft_net;
++ struct nft_ctx ctx = {};
++
++ nft_net = nft_pernet(trans->net);
++
++ mutex_lock(&nft_net->commit_mutex);
++
++ /* Check for race with transaction, otherwise this batch refers to
++ * stale objects that might not be there anymore. Skip transaction if
++ * set has been destroyed from control plane transaction in case gc
++ * worker loses race.
++ */
++ if (READ_ONCE(nft_net->gc_seq) != trans->seq || trans->set->dead) {
++ mutex_unlock(&nft_net->commit_mutex);
++ return false;
++ }
++
++ ctx.net = trans->net;
++ ctx.table = trans->set->table;
++
++ nft_trans_gc_setelem_remove(&ctx, trans);
++ mutex_unlock(&nft_net->commit_mutex);
++
++ return true;
++}
++
++static void nft_trans_gc_work(struct work_struct *work)
++{
++ struct nft_trans_gc *trans, *next;
++ LIST_HEAD(trans_gc_list);
++
++ spin_lock(&nf_tables_destroy_list_lock);
++ list_splice_init(&nf_tables_gc_list, &trans_gc_list);
++ spin_unlock(&nf_tables_destroy_list_lock);
++
++ list_for_each_entry_safe(trans, next, &trans_gc_list, list) {
++ list_del(&trans->list);
++ if (!nft_trans_gc_work_done(trans)) {
++ nft_trans_gc_destroy(trans);
++ continue;
++ }
++ call_rcu(&trans->rcu, nft_trans_gc_trans_free);
++ }
++}
++
++struct nft_trans_gc *nft_trans_gc_alloc(struct nft_set *set,
++ unsigned int gc_seq, gfp_t gfp)
++{
++ struct net *net = read_pnet(&set->net);
++ struct nft_trans_gc *trans;
++
++ trans = kzalloc(sizeof(*trans), gfp);
++ if (!trans)
++ return NULL;
++
++ refcount_inc(&set->refs);
++ trans->set = set;
++ trans->net = get_net(net);
++ trans->seq = gc_seq;
++
++ return trans;
++}
++
++void nft_trans_gc_elem_add(struct nft_trans_gc *trans, void *priv)
++{
++ trans->priv[trans->count++] = priv;
++}
++
++static void nft_trans_gc_queue_work(struct nft_trans_gc *trans)
++{
++ spin_lock(&nf_tables_gc_list_lock);
++ list_add_tail(&trans->list, &nf_tables_gc_list);
++ spin_unlock(&nf_tables_gc_list_lock);
++
++ schedule_work(&trans_gc_work);
++}
++
++static int nft_trans_gc_space(struct nft_trans_gc *trans)
++{
++ return NFT_TRANS_GC_BATCHCOUNT - trans->count;
++}
++
++struct nft_trans_gc *nft_trans_gc_queue_async(struct nft_trans_gc *gc,
++ unsigned int gc_seq, gfp_t gfp)
++{
++ if (nft_trans_gc_space(gc))
++ return gc;
++
++ nft_trans_gc_queue_work(gc);
++
++ return nft_trans_gc_alloc(gc->set, gc_seq, gfp);
++}
++
++void nft_trans_gc_queue_async_done(struct nft_trans_gc *trans)
++{
++ if (trans->count == 0) {
++ nft_trans_gc_destroy(trans);
++ return;
++ }
++
++ nft_trans_gc_queue_work(trans);
++}
++
++struct nft_trans_gc *nft_trans_gc_queue_sync(struct nft_trans_gc *gc, gfp_t gfp)
++{
++ if (WARN_ON_ONCE(!lockdep_commit_lock_is_held(gc->net)))
++ return NULL;
++
++ if (nft_trans_gc_space(gc))
++ return gc;
++
++ call_rcu(&gc->rcu, nft_trans_gc_trans_free);
++
++ return nft_trans_gc_alloc(gc->set, 0, gfp);
++}
++
++void nft_trans_gc_queue_sync_done(struct nft_trans_gc *trans)
++{
++ WARN_ON_ONCE(!lockdep_commit_lock_is_held(trans->net));
++
++ if (trans->count == 0) {
++ nft_trans_gc_destroy(trans);
++ return;
++ }
++
++ call_rcu(&trans->rcu, nft_trans_gc_trans_free);
++}
++
++struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc,
++ unsigned int gc_seq)
++{
++ struct nft_set_elem_catchall *catchall;
++ const struct nft_set *set = gc->set;
++ struct nft_set_ext *ext;
++
++ list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
++ ext = nft_set_elem_ext(set, catchall->elem);
++
++ if (!nft_set_elem_expired(ext))
++ continue;
++ if (nft_set_elem_is_dead(ext))
++ goto dead_elem;
++
++ nft_set_elem_dead(ext);
++dead_elem:
++ gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC);
++ if (!gc)
++ return NULL;
++
++ nft_trans_gc_elem_add(gc, catchall->elem);
++ }
++
++ return gc;
++}
++
+ static void nf_tables_module_autoload_cleanup(struct net *net)
+ {
+ struct nftables_pernet *nft_net = nft_pernet(net);
+@@ -9250,11 +9461,11 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
+ {
+ struct nftables_pernet *nft_net = nft_pernet(net);
+ struct nft_trans *trans, *next;
++ unsigned int base_seq, gc_seq;
+ LIST_HEAD(set_update_list);
+ struct nft_trans_elem *te;
+ struct nft_chain *chain;
+ struct nft_table *table;
+- unsigned int base_seq;
+ LIST_HEAD(adl);
+ int err;
+
+@@ -9331,6 +9542,10 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
+
+ WRITE_ONCE(nft_net->base_seq, base_seq);
+
++ /* Bump gc counter, it becomes odd, this is the busy mark. */
++ gc_seq = READ_ONCE(nft_net->gc_seq);
++ WRITE_ONCE(nft_net->gc_seq, ++gc_seq);
++
+ /* step 3. Start new generation, rules_gen_X now in use. */
+ net->nft.gencursor = nft_gencursor_next(net);
+
+@@ -9419,6 +9634,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
+ nft_trans_destroy(trans);
+ break;
+ case NFT_MSG_DELSET:
++ nft_trans_set(trans)->dead = 1;
+ list_del_rcu(&nft_trans_set(trans)->list);
+ nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
+ NFT_MSG_DELSET, GFP_KERNEL);
+@@ -9518,6 +9734,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
+ nft_commit_notify(net, NETLINK_CB(skb).portid);
+ nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN);
+ nf_tables_commit_audit_log(&adl, nft_net->base_seq);
++
++ WRITE_ONCE(nft_net->gc_seq, ++gc_seq);
+ nf_tables_commit_release(net);
+
+ return 0;
+@@ -10549,6 +10767,7 @@ static int __net_init nf_tables_init_net(struct net *net)
+ INIT_LIST_HEAD(&nft_net->notify_list);
+ mutex_init(&nft_net->commit_mutex);
+ nft_net->base_seq = 1;
++ nft_net->gc_seq = 0;
+
+ return 0;
+ }
+@@ -10577,10 +10796,16 @@ static void __net_exit nf_tables_exit_net(struct net *net)
+ WARN_ON_ONCE(!list_empty(&nft_net->notify_list));
+ }
+
++static void nf_tables_exit_batch(struct list_head *net_exit_list)
++{
++ flush_work(&trans_gc_work);
++}
++
+ static struct pernet_operations nf_tables_net_ops = {
+ .init = nf_tables_init_net,
+ .pre_exit = nf_tables_pre_exit_net,
+ .exit = nf_tables_exit_net,
++ .exit_batch = nf_tables_exit_batch,
+ .id = &nf_tables_net_id,
+ .size = sizeof(struct nftables_pernet),
+ };
+@@ -10652,6 +10877,7 @@ static void __exit nf_tables_module_exit(void)
+ nft_chain_filter_fini();
+ nft_chain_route_fini();
+ unregister_pernet_subsys(&nf_tables_net_ops);
++ cancel_work_sync(&trans_gc_work);
+ cancel_work_sync(&trans_destroy_work);
+ rcu_barrier();
+ rhltable_destroy(&nft_objname_ht);
+--
+2.40.1
+
--- /dev/null
+From f21c339a0ae22256625afacf18c14cfeffb6e63b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Aug 2023 15:39:01 +0200
+Subject: netfilter: nf_tables: GC transaction race with netns dismantle
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 02c6c24402bf1c1e986899c14ba22a10b510916b ]
+
+Use maybe_get_net() since GC workqueue might race with netns exit path.
+
+Fixes: 5f68718b34a5 ("netfilter: nf_tables: GC transaction API to avoid race with control plane")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index c0f1eccf2283d..1624a5ca90fe8 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -9150,9 +9150,14 @@ struct nft_trans_gc *nft_trans_gc_alloc(struct nft_set *set,
+ if (!trans)
+ return NULL;
+
++ trans->net = maybe_get_net(net);
++ if (!trans->net) {
++ kfree(trans);
++ return NULL;
++ }
++
+ refcount_inc(&set->refs);
+ trans->set = set;
+- trans->net = get_net(net);
+ trans->seq = gc_seq;
+
+ return trans;
+--
+2.40.1
+
--- /dev/null
+From 0fba82aaaed4af9a80b285f0ab53d935bb18f9f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Apr 2023 17:13:20 +0200
+Subject: netfilter: nf_tables: make validation state per table
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 00c320f9b75560628e840bef027a27c746706759 ]
+
+We only need to validate tables that saw changes in the current
+transaction.
+
+The existing code revalidates all tables, but this isn't needed as
+cross-table jumps are not allowed (chains have table scope).
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Stable-dep-of: 5f68718b34a5 ("netfilter: nf_tables: GC transaction API to avoid race with control plane")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netfilter/nf_tables.h | 3 ++-
+ net/netfilter/nf_tables_api.c | 38 +++++++++++++++----------------
+ 2 files changed, 20 insertions(+), 21 deletions(-)
+
+diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
+index c752b6f509791..120be22ef6aa2 100644
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -1231,6 +1231,7 @@ static inline void nft_use_inc_restore(u32 *use)
+ * @genmask: generation mask
+ * @afinfo: address family info
+ * @name: name of the table
++ * @validate_state: internal, set when transaction adds jumps
+ */
+ struct nft_table {
+ struct list_head list;
+@@ -1249,6 +1250,7 @@ struct nft_table {
+ char *name;
+ u16 udlen;
+ u8 *udata;
++ u8 validate_state;
+ };
+
+ static inline bool nft_table_has_owner(const struct nft_table *table)
+@@ -1734,7 +1736,6 @@ struct nftables_pernet {
+ struct mutex commit_mutex;
+ u64 table_handle;
+ unsigned int base_seq;
+- u8 validate_state;
+ };
+
+ extern unsigned int nf_tables_net_id;
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 3c5cac9bd9b70..a013d2a31f0b8 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -102,11 +102,9 @@ static const u8 nft2audit_op[NFT_MSG_MAX] = { // enum nf_tables_msg_types
+ [NFT_MSG_DELFLOWTABLE] = AUDIT_NFT_OP_FLOWTABLE_UNREGISTER,
+ };
+
+-static void nft_validate_state_update(struct net *net, u8 new_validate_state)
++static void nft_validate_state_update(struct nft_table *table, u8 new_validate_state)
+ {
+- struct nftables_pernet *nft_net = nft_pernet(net);
+-
+- switch (nft_net->validate_state) {
++ switch (table->validate_state) {
+ case NFT_VALIDATE_SKIP:
+ WARN_ON_ONCE(new_validate_state == NFT_VALIDATE_DO);
+ break;
+@@ -117,7 +115,7 @@ static void nft_validate_state_update(struct net *net, u8 new_validate_state)
+ return;
+ }
+
+- nft_net->validate_state = new_validate_state;
++ table->validate_state = new_validate_state;
+ }
+ static void nf_tables_trans_destroy_work(struct work_struct *w);
+ static DECLARE_WORK(trans_destroy_work, nf_tables_trans_destroy_work);
+@@ -1365,6 +1363,7 @@ static int nf_tables_newtable(struct sk_buff *skb, const struct nfnl_info *info,
+ if (table == NULL)
+ goto err_kzalloc;
+
++ table->validate_state = NFT_VALIDATE_SKIP;
+ table->name = nla_strdup(attr, GFP_KERNEL_ACCOUNT);
+ if (table->name == NULL)
+ goto err_strdup;
+@@ -3747,7 +3746,7 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
+ }
+
+ if (expr_info[i].ops->validate)
+- nft_validate_state_update(net, NFT_VALIDATE_NEED);
++ nft_validate_state_update(table, NFT_VALIDATE_NEED);
+
+ expr_info[i].ops = NULL;
+ expr = nft_expr_next(expr);
+@@ -3801,7 +3800,7 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
+ if (flow)
+ nft_trans_flow_rule(trans) = flow;
+
+- if (nft_net->validate_state == NFT_VALIDATE_DO)
++ if (table->validate_state == NFT_VALIDATE_DO)
+ return nft_table_validate(net, table);
+
+ return 0;
+@@ -6492,7 +6491,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+ if (desc.type == NFT_DATA_VERDICT &&
+ (elem.data.val.verdict.code == NFT_GOTO ||
+ elem.data.val.verdict.code == NFT_JUMP))
+- nft_validate_state_update(ctx->net,
++ nft_validate_state_update(ctx->table,
+ NFT_VALIDATE_NEED);
+ }
+
+@@ -6616,7 +6615,6 @@ static int nf_tables_newsetelem(struct sk_buff *skb,
+ const struct nfnl_info *info,
+ const struct nlattr * const nla[])
+ {
+- struct nftables_pernet *nft_net = nft_pernet(info->net);
+ struct netlink_ext_ack *extack = info->extack;
+ u8 genmask = nft_genmask_next(info->net);
+ u8 family = info->nfmsg->nfgen_family;
+@@ -6656,7 +6654,7 @@ static int nf_tables_newsetelem(struct sk_buff *skb,
+ }
+ }
+
+- if (nft_net->validate_state == NFT_VALIDATE_DO)
++ if (table->validate_state == NFT_VALIDATE_DO)
+ return nft_table_validate(net, table);
+
+ return 0;
+@@ -8757,19 +8755,20 @@ static int nf_tables_validate(struct net *net)
+ struct nftables_pernet *nft_net = nft_pernet(net);
+ struct nft_table *table;
+
+- switch (nft_net->validate_state) {
+- case NFT_VALIDATE_SKIP:
+- break;
+- case NFT_VALIDATE_NEED:
+- nft_validate_state_update(net, NFT_VALIDATE_DO);
+- fallthrough;
+- case NFT_VALIDATE_DO:
+- list_for_each_entry(table, &nft_net->tables, list) {
++ list_for_each_entry(table, &nft_net->tables, list) {
++ switch (table->validate_state) {
++ case NFT_VALIDATE_SKIP:
++ continue;
++ case NFT_VALIDATE_NEED:
++ nft_validate_state_update(table, NFT_VALIDATE_DO);
++ fallthrough;
++ case NFT_VALIDATE_DO:
+ if (nft_table_validate(net, table) < 0)
+ return -EAGAIN;
++
++ nft_validate_state_update(table, NFT_VALIDATE_SKIP);
+ }
+
+- nft_validate_state_update(net, NFT_VALIDATE_SKIP);
+ break;
+ }
+
+@@ -10550,7 +10549,6 @@ static int __net_init nf_tables_init_net(struct net *net)
+ INIT_LIST_HEAD(&nft_net->notify_list);
+ mutex_init(&nft_net->commit_mutex);
+ nft_net->base_seq = 1;
+- nft_net->validate_state = NFT_VALIDATE_SKIP;
+
+ return 0;
+ }
+--
+2.40.1
+
--- /dev/null
+From f98f3ca66166f3d4b05e14b38f7c42766b466950 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 15:00:36 +0200
+Subject: netfilter: nf_tables: remove busy mark and gc batch API
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit a2dd0233cbc4d8a0abb5f64487487ffc9265beb5 ]
+
+Ditch it, it has been replace it by the GC transaction API and it has no
+clients anymore.
+
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netfilter/nf_tables.h | 98 +------------------------------
+ net/netfilter/nf_tables_api.c | 48 +--------------
+ 2 files changed, 4 insertions(+), 142 deletions(-)
+
+diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
+index 483b106466f3d..143c6db05be52 100644
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -594,7 +594,6 @@ struct nft_set *nft_set_lookup_global(const struct net *net,
+
+ struct nft_set_ext *nft_set_catchall_lookup(const struct net *net,
+ const struct nft_set *set);
+-void *nft_set_catchall_gc(const struct nft_set *set);
+
+ static inline unsigned long nft_set_gc_interval(const struct nft_set *set)
+ {
+@@ -811,62 +810,6 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem,
+ void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
+ const struct nft_set *set, void *elem);
+
+-/**
+- * struct nft_set_gc_batch_head - nf_tables set garbage collection batch
+- *
+- * @rcu: rcu head
+- * @set: set the elements belong to
+- * @cnt: count of elements
+- */
+-struct nft_set_gc_batch_head {
+- struct rcu_head rcu;
+- const struct nft_set *set;
+- unsigned int cnt;
+-};
+-
+-#define NFT_SET_GC_BATCH_SIZE ((PAGE_SIZE - \
+- sizeof(struct nft_set_gc_batch_head)) / \
+- sizeof(void *))
+-
+-/**
+- * struct nft_set_gc_batch - nf_tables set garbage collection batch
+- *
+- * @head: GC batch head
+- * @elems: garbage collection elements
+- */
+-struct nft_set_gc_batch {
+- struct nft_set_gc_batch_head head;
+- void *elems[NFT_SET_GC_BATCH_SIZE];
+-};
+-
+-struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
+- gfp_t gfp);
+-void nft_set_gc_batch_release(struct rcu_head *rcu);
+-
+-static inline void nft_set_gc_batch_complete(struct nft_set_gc_batch *gcb)
+-{
+- if (gcb != NULL)
+- call_rcu(&gcb->head.rcu, nft_set_gc_batch_release);
+-}
+-
+-static inline struct nft_set_gc_batch *
+-nft_set_gc_batch_check(const struct nft_set *set, struct nft_set_gc_batch *gcb,
+- gfp_t gfp)
+-{
+- if (gcb != NULL) {
+- if (gcb->head.cnt + 1 < ARRAY_SIZE(gcb->elems))
+- return gcb;
+- nft_set_gc_batch_complete(gcb);
+- }
+- return nft_set_gc_batch_alloc(set, gfp);
+-}
+-
+-static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb,
+- void *elem)
+-{
+- gcb->elems[gcb->head.cnt++] = elem;
+-}
+-
+ struct nft_expr_ops;
+ /**
+ * struct nft_expr_type - nf_tables expression type
+@@ -1547,47 +1490,12 @@ static inline void nft_set_elem_change_active(const struct net *net,
+
+ #endif /* IS_ENABLED(CONFIG_NF_TABLES) */
+
+-/*
+- * We use a free bit in the genmask field to indicate the element
+- * is busy, meaning it is currently being processed either by
+- * the netlink API or GC.
+- *
+- * Even though the genmask is only a single byte wide, this works
+- * because the extension structure if fully constant once initialized,
+- * so there are no non-atomic write accesses unless it is already
+- * marked busy.
+- */
+-#define NFT_SET_ELEM_BUSY_MASK (1 << 2)
+-
+-#if defined(__LITTLE_ENDIAN_BITFIELD)
+-#define NFT_SET_ELEM_BUSY_BIT 2
+-#elif defined(__BIG_ENDIAN_BITFIELD)
+-#define NFT_SET_ELEM_BUSY_BIT (BITS_PER_LONG - BITS_PER_BYTE + 2)
+-#else
+-#error
+-#endif
+-
+-static inline int nft_set_elem_mark_busy(struct nft_set_ext *ext)
+-{
+- unsigned long *word = (unsigned long *)ext;
+-
+- BUILD_BUG_ON(offsetof(struct nft_set_ext, genmask) != 0);
+- return test_and_set_bit(NFT_SET_ELEM_BUSY_BIT, word);
+-}
+-
+-static inline void nft_set_elem_clear_busy(struct nft_set_ext *ext)
+-{
+- unsigned long *word = (unsigned long *)ext;
+-
+- clear_bit(NFT_SET_ELEM_BUSY_BIT, word);
+-}
+-
+-#define NFT_SET_ELEM_DEAD_MASK (1 << 3)
++#define NFT_SET_ELEM_DEAD_MASK (1 << 2)
+
+ #if defined(__LITTLE_ENDIAN_BITFIELD)
+-#define NFT_SET_ELEM_DEAD_BIT 3
++#define NFT_SET_ELEM_DEAD_BIT 2
+ #elif defined(__BIG_ENDIAN_BITFIELD)
+-#define NFT_SET_ELEM_DEAD_BIT (BITS_PER_LONG - BITS_PER_BYTE + 3)
++#define NFT_SET_ELEM_DEAD_BIT (BITS_PER_LONG - BITS_PER_BYTE + 2)
+ #else
+ #error
+ #endif
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 35d84e8b79524..2f8290e175ad7 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -6064,29 +6064,6 @@ struct nft_set_ext *nft_set_catchall_lookup(const struct net *net,
+ }
+ EXPORT_SYMBOL_GPL(nft_set_catchall_lookup);
+
+-void *nft_set_catchall_gc(const struct nft_set *set)
+-{
+- struct nft_set_elem_catchall *catchall, *next;
+- struct nft_set_ext *ext;
+- void *elem = NULL;
+-
+- list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
+- ext = nft_set_elem_ext(set, catchall->elem);
+-
+- if (!nft_set_elem_expired(ext) ||
+- nft_set_elem_mark_busy(ext))
+- continue;
+-
+- elem = catchall->elem;
+- list_del_rcu(&catchall->list);
+- kfree_rcu(catchall, rcu);
+- break;
+- }
+-
+- return elem;
+-}
+-EXPORT_SYMBOL_GPL(nft_set_catchall_gc);
+-
+ static int nft_setelem_catchall_insert(const struct net *net,
+ struct nft_set *set,
+ const struct nft_set_elem *elem,
+@@ -6557,7 +6534,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+ goto err_elem_free;
+ }
+
+- ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK;
++ ext->genmask = nft_genmask_cur(ctx->net);
+
+ err = nft_setelem_insert(ctx->net, set, &elem, &ext2, flags);
+ if (err) {
+@@ -6943,29 +6920,6 @@ static int nf_tables_delsetelem(struct sk_buff *skb,
+ return err;
+ }
+
+-void nft_set_gc_batch_release(struct rcu_head *rcu)
+-{
+- struct nft_set_gc_batch *gcb;
+- unsigned int i;
+-
+- gcb = container_of(rcu, struct nft_set_gc_batch, head.rcu);
+- for (i = 0; i < gcb->head.cnt; i++)
+- nft_set_elem_destroy(gcb->head.set, gcb->elems[i], true);
+- kfree(gcb);
+-}
+-
+-struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
+- gfp_t gfp)
+-{
+- struct nft_set_gc_batch *gcb;
+-
+- gcb = kzalloc(sizeof(*gcb), gfp);
+- if (gcb == NULL)
+- return gcb;
+- gcb->head.set = set;
+- return gcb;
+-}
+-
+ /*
+ * Stateful objects
+ */
+--
+2.40.1
+
--- /dev/null
+From e12238c7ff338cc87bbb51797345ecd3939f5353 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 15:00:06 +0200
+Subject: netfilter: nft_set_hash: mark set element as dead when deleting from
+ packet path
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit c92db3030492b8ad1d0faace7a93bbcf53850d0c ]
+
+Set on the NFT_SET_ELEM_DEAD_BIT flag on this element, instead of
+performing element removal which might race with an ongoing transaction.
+Enable gc when dynamic flag is set on since dynset deletion requires
+garbage collection after this patch.
+
+Fixes: d0a8d877da97 ("netfilter: nft_dynset: support for element deletion")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_set_hash.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c
+index 960cbd56c0406..8dfa97105d8a3 100644
+--- a/net/netfilter/nft_set_hash.c
++++ b/net/netfilter/nft_set_hash.c
+@@ -249,7 +249,9 @@ static bool nft_rhash_delete(const struct nft_set *set,
+ if (he == NULL)
+ return false;
+
+- return rhashtable_remove_fast(&priv->ht, &he->node, nft_rhash_params) == 0;
++ nft_set_elem_dead(&he->ext);
++
++ return true;
+ }
+
+ static void nft_rhash_walk(const struct nft_ctx *ctx, struct nft_set *set,
+@@ -414,7 +416,7 @@ static int nft_rhash_init(const struct nft_set *set,
+ return err;
+
+ INIT_DEFERRABLE_WORK(&priv->gc_work, nft_rhash_gc);
+- if (set->flags & NFT_SET_TIMEOUT)
++ if (set->flags & (NFT_SET_TIMEOUT | NFT_SET_EVAL))
+ nft_rhash_gc_init(set);
+
+ return 0;
+--
+2.40.1
+
--- /dev/null
+From ab0d44f51994d7ac24339839843bc839b4d554c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Aug 2023 07:22:26 +0000
+Subject: netlink: convert nlk->flags to atomic flags
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 8fe08d70a2b61b35a0a1235c78cf321e7528351f ]
+
+sk_diag_put_flags(), netlink_setsockopt(), netlink_getsockopt()
+and others use nlk->flags without correct locking.
+
+Use set_bit(), clear_bit(), test_bit(), assign_bit() to remove
+data-races.
+
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netlink/af_netlink.c | 90 ++++++++++++++--------------------------
+ net/netlink/af_netlink.h | 22 ++++++----
+ net/netlink/diag.c | 10 ++---
+ 3 files changed, 48 insertions(+), 74 deletions(-)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index ed123cf462afe..387e430a35ccc 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -84,7 +84,7 @@ struct listeners {
+
+ static inline int netlink_is_kernel(struct sock *sk)
+ {
+- return nlk_sk(sk)->flags & NETLINK_F_KERNEL_SOCKET;
++ return nlk_test_bit(KERNEL_SOCKET, sk);
+ }
+
+ struct netlink_table *nl_table __read_mostly;
+@@ -349,9 +349,7 @@ static void netlink_deliver_tap_kernel(struct sock *dst, struct sock *src,
+
+ static void netlink_overrun(struct sock *sk)
+ {
+- struct netlink_sock *nlk = nlk_sk(sk);
+-
+- if (!(nlk->flags & NETLINK_F_RECV_NO_ENOBUFS)) {
++ if (!nlk_test_bit(RECV_NO_ENOBUFS, sk)) {
+ if (!test_and_set_bit(NETLINK_S_CONGESTED,
+ &nlk_sk(sk)->state)) {
+ sk->sk_err = ENOBUFS;
+@@ -1391,9 +1389,7 @@ EXPORT_SYMBOL_GPL(netlink_has_listeners);
+
+ bool netlink_strict_get_check(struct sk_buff *skb)
+ {
+- const struct netlink_sock *nlk = nlk_sk(NETLINK_CB(skb).sk);
+-
+- return nlk->flags & NETLINK_F_STRICT_CHK;
++ return nlk_test_bit(STRICT_CHK, NETLINK_CB(skb).sk);
+ }
+ EXPORT_SYMBOL_GPL(netlink_strict_get_check);
+
+@@ -1437,7 +1433,7 @@ static void do_one_broadcast(struct sock *sk,
+ return;
+
+ if (!net_eq(sock_net(sk), p->net)) {
+- if (!(nlk->flags & NETLINK_F_LISTEN_ALL_NSID))
++ if (!nlk_test_bit(LISTEN_ALL_NSID, sk))
+ return;
+
+ if (!peernet_has_id(sock_net(sk), p->net))
+@@ -1470,7 +1466,7 @@ static void do_one_broadcast(struct sock *sk,
+ netlink_overrun(sk);
+ /* Clone failed. Notify ALL listeners. */
+ p->failure = 1;
+- if (nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR)
++ if (nlk_test_bit(BROADCAST_SEND_ERROR, sk))
+ p->delivery_failure = 1;
+ goto out;
+ }
+@@ -1485,7 +1481,7 @@ static void do_one_broadcast(struct sock *sk,
+ val = netlink_broadcast_deliver(sk, p->skb2);
+ if (val < 0) {
+ netlink_overrun(sk);
+- if (nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR)
++ if (nlk_test_bit(BROADCAST_SEND_ERROR, sk))
+ p->delivery_failure = 1;
+ } else {
+ p->congested |= val;
+@@ -1565,7 +1561,7 @@ static int do_one_set_err(struct sock *sk, struct netlink_set_err_data *p)
+ !test_bit(p->group - 1, nlk->groups))
+ goto out;
+
+- if (p->code == ENOBUFS && nlk->flags & NETLINK_F_RECV_NO_ENOBUFS) {
++ if (p->code == ENOBUFS && nlk_test_bit(RECV_NO_ENOBUFS, sk)) {
+ ret = 1;
+ goto out;
+ }
+@@ -1632,7 +1628,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
+ struct sock *sk = sock->sk;
+ struct netlink_sock *nlk = nlk_sk(sk);
+ unsigned int val = 0;
+- int err;
++ int nr = -1;
+
+ if (level != SOL_NETLINK)
+ return -ENOPROTOOPT;
+@@ -1643,14 +1639,12 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
+
+ switch (optname) {
+ case NETLINK_PKTINFO:
+- if (val)
+- nlk->flags |= NETLINK_F_RECV_PKTINFO;
+- else
+- nlk->flags &= ~NETLINK_F_RECV_PKTINFO;
+- err = 0;
++ nr = NETLINK_F_RECV_PKTINFO;
+ break;
+ case NETLINK_ADD_MEMBERSHIP:
+ case NETLINK_DROP_MEMBERSHIP: {
++ int err;
++
+ if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV))
+ return -EPERM;
+ err = netlink_realloc_groups(sk);
+@@ -1670,61 +1664,38 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
+ if (optname == NETLINK_DROP_MEMBERSHIP && nlk->netlink_unbind)
+ nlk->netlink_unbind(sock_net(sk), val);
+
+- err = 0;
+ break;
+ }
+ case NETLINK_BROADCAST_ERROR:
+- if (val)
+- nlk->flags |= NETLINK_F_BROADCAST_SEND_ERROR;
+- else
+- nlk->flags &= ~NETLINK_F_BROADCAST_SEND_ERROR;
+- err = 0;
++ nr = NETLINK_F_BROADCAST_SEND_ERROR;
+ break;
+ case NETLINK_NO_ENOBUFS:
++ assign_bit(NETLINK_F_RECV_NO_ENOBUFS, &nlk->flags, val);
+ if (val) {
+- nlk->flags |= NETLINK_F_RECV_NO_ENOBUFS;
+ clear_bit(NETLINK_S_CONGESTED, &nlk->state);
+ wake_up_interruptible(&nlk->wait);
+- } else {
+- nlk->flags &= ~NETLINK_F_RECV_NO_ENOBUFS;
+ }
+- err = 0;
+ break;
+ case NETLINK_LISTEN_ALL_NSID:
+ if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_BROADCAST))
+ return -EPERM;
+-
+- if (val)
+- nlk->flags |= NETLINK_F_LISTEN_ALL_NSID;
+- else
+- nlk->flags &= ~NETLINK_F_LISTEN_ALL_NSID;
+- err = 0;
++ nr = NETLINK_F_LISTEN_ALL_NSID;
+ break;
+ case NETLINK_CAP_ACK:
+- if (val)
+- nlk->flags |= NETLINK_F_CAP_ACK;
+- else
+- nlk->flags &= ~NETLINK_F_CAP_ACK;
+- err = 0;
++ nr = NETLINK_F_CAP_ACK;
+ break;
+ case NETLINK_EXT_ACK:
+- if (val)
+- nlk->flags |= NETLINK_F_EXT_ACK;
+- else
+- nlk->flags &= ~NETLINK_F_EXT_ACK;
+- err = 0;
++ nr = NETLINK_F_EXT_ACK;
+ break;
+ case NETLINK_GET_STRICT_CHK:
+- if (val)
+- nlk->flags |= NETLINK_F_STRICT_CHK;
+- else
+- nlk->flags &= ~NETLINK_F_STRICT_CHK;
+- err = 0;
++ nr = NETLINK_F_STRICT_CHK;
+ break;
+ default:
+- err = -ENOPROTOOPT;
++ return -ENOPROTOOPT;
+ }
+- return err;
++ if (nr >= 0)
++ assign_bit(nr, &nlk->flags, val);
++ return 0;
+ }
+
+ static int netlink_getsockopt(struct socket *sock, int level, int optname,
+@@ -1791,7 +1762,7 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname,
+ return -EINVAL;
+
+ len = sizeof(int);
+- val = nlk->flags & flag ? 1 : 0;
++ val = test_bit(flag, &nlk->flags);
+
+ if (put_user(len, optlen) ||
+ copy_to_user(optval, &val, len))
+@@ -1968,9 +1939,9 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
+ msg->msg_namelen = sizeof(*addr);
+ }
+
+- if (nlk->flags & NETLINK_F_RECV_PKTINFO)
++ if (nlk_test_bit(RECV_PKTINFO, sk))
+ netlink_cmsg_recv_pktinfo(msg, skb);
+- if (nlk->flags & NETLINK_F_LISTEN_ALL_NSID)
++ if (nlk_test_bit(LISTEN_ALL_NSID, sk))
+ netlink_cmsg_listen_all_nsid(sk, msg, skb);
+
+ memset(&scm, 0, sizeof(scm));
+@@ -2047,7 +2018,7 @@ __netlink_kernel_create(struct net *net, int unit, struct module *module,
+ goto out_sock_release;
+
+ nlk = nlk_sk(sk);
+- nlk->flags |= NETLINK_F_KERNEL_SOCKET;
++ set_bit(NETLINK_F_KERNEL_SOCKET, &nlk->flags);
+
+ netlink_table_grab();
+ if (!nl_table[unit].registered) {
+@@ -2183,7 +2154,7 @@ static int netlink_dump_done(struct netlink_sock *nlk, struct sk_buff *skb,
+ nl_dump_check_consistent(cb, nlh);
+ memcpy(nlmsg_data(nlh), &nlk->dump_done_errno, sizeof(nlk->dump_done_errno));
+
+- if (extack->_msg && nlk->flags & NETLINK_F_EXT_ACK) {
++ if (extack->_msg && test_bit(NETLINK_F_EXT_ACK, &nlk->flags)) {
+ nlh->nlmsg_flags |= NLM_F_ACK_TLVS;
+ if (!nla_put_string(skb, NLMSGERR_ATTR_MSG, extack->_msg))
+ nlmsg_end(skb, nlh);
+@@ -2312,8 +2283,8 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
+ const struct nlmsghdr *nlh,
+ struct netlink_dump_control *control)
+ {
+- struct netlink_sock *nlk, *nlk2;
+ struct netlink_callback *cb;
++ struct netlink_sock *nlk;
+ struct sock *sk;
+ int ret;
+
+@@ -2348,8 +2319,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
+ cb->min_dump_alloc = control->min_dump_alloc;
+ cb->skb = skb;
+
+- nlk2 = nlk_sk(NETLINK_CB(skb).sk);
+- cb->strict_check = !!(nlk2->flags & NETLINK_F_STRICT_CHK);
++ cb->strict_check = nlk_test_bit(STRICT_CHK, NETLINK_CB(skb).sk);
+
+ if (control->start) {
+ ret = control->start(cb);
+@@ -2391,7 +2361,7 @@ netlink_ack_tlv_len(struct netlink_sock *nlk, int err,
+ {
+ size_t tlvlen;
+
+- if (!extack || !(nlk->flags & NETLINK_F_EXT_ACK))
++ if (!extack || !test_bit(NETLINK_F_EXT_ACK, &nlk->flags))
+ return 0;
+
+ tlvlen = 0;
+@@ -2463,7 +2433,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
+ * requests to cap the error message, and get extra error data if
+ * requested.
+ */
+- if (err && !(nlk->flags & NETLINK_F_CAP_ACK))
++ if (err && !test_bit(NETLINK_F_CAP_ACK, &nlk->flags))
+ payload += nlmsg_len(nlh);
+ else
+ flags |= NLM_F_CAPPED;
+diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h
+index 5f454c8de6a4d..b30b8fc760f71 100644
+--- a/net/netlink/af_netlink.h
++++ b/net/netlink/af_netlink.h
+@@ -8,14 +8,16 @@
+ #include <net/sock.h>
+
+ /* flags */
+-#define NETLINK_F_KERNEL_SOCKET 0x1
+-#define NETLINK_F_RECV_PKTINFO 0x2
+-#define NETLINK_F_BROADCAST_SEND_ERROR 0x4
+-#define NETLINK_F_RECV_NO_ENOBUFS 0x8
+-#define NETLINK_F_LISTEN_ALL_NSID 0x10
+-#define NETLINK_F_CAP_ACK 0x20
+-#define NETLINK_F_EXT_ACK 0x40
+-#define NETLINK_F_STRICT_CHK 0x80
++enum {
++ NETLINK_F_KERNEL_SOCKET,
++ NETLINK_F_RECV_PKTINFO,
++ NETLINK_F_BROADCAST_SEND_ERROR,
++ NETLINK_F_RECV_NO_ENOBUFS,
++ NETLINK_F_LISTEN_ALL_NSID,
++ NETLINK_F_CAP_ACK,
++ NETLINK_F_EXT_ACK,
++ NETLINK_F_STRICT_CHK,
++};
+
+ #define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8)
+ #define NLGRPLONGS(x) (NLGRPSZ(x)/sizeof(unsigned long))
+@@ -23,10 +25,10 @@
+ struct netlink_sock {
+ /* struct sock has to be the first member of netlink_sock */
+ struct sock sk;
++ unsigned long flags;
+ u32 portid;
+ u32 dst_portid;
+ u32 dst_group;
+- u32 flags;
+ u32 subscriptions;
+ u32 ngroups;
+ unsigned long *groups;
+@@ -54,6 +56,8 @@ static inline struct netlink_sock *nlk_sk(struct sock *sk)
+ return container_of(sk, struct netlink_sock, sk);
+ }
+
++#define nlk_test_bit(nr, sk) test_bit(NETLINK_F_##nr, &nlk_sk(sk)->flags)
++
+ struct netlink_table {
+ struct rhashtable hash;
+ struct hlist_head mc_list;
+diff --git a/net/netlink/diag.c b/net/netlink/diag.c
+index e4f21b1067bcc..9c4f231be2757 100644
+--- a/net/netlink/diag.c
++++ b/net/netlink/diag.c
+@@ -27,15 +27,15 @@ static int sk_diag_put_flags(struct sock *sk, struct sk_buff *skb)
+
+ if (nlk->cb_running)
+ flags |= NDIAG_FLAG_CB_RUNNING;
+- if (nlk->flags & NETLINK_F_RECV_PKTINFO)
++ if (nlk_test_bit(RECV_PKTINFO, sk))
+ flags |= NDIAG_FLAG_PKTINFO;
+- if (nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR)
++ if (nlk_test_bit(BROADCAST_SEND_ERROR, sk))
+ flags |= NDIAG_FLAG_BROADCAST_ERROR;
+- if (nlk->flags & NETLINK_F_RECV_NO_ENOBUFS)
++ if (nlk_test_bit(RECV_NO_ENOBUFS, sk))
+ flags |= NDIAG_FLAG_NO_ENOBUFS;
+- if (nlk->flags & NETLINK_F_LISTEN_ALL_NSID)
++ if (nlk_test_bit(LISTEN_ALL_NSID, sk))
+ flags |= NDIAG_FLAG_LISTEN_ALL_NSID;
+- if (nlk->flags & NETLINK_F_CAP_ACK)
++ if (nlk_test_bit(CAP_ACK, sk))
+ flags |= NDIAG_FLAG_CAP_ACK;
+
+ return nla_put_u32(skb, NETLINK_DIAG_FLAGS, flags);
+--
+2.40.1
+
--- /dev/null
+From 45dc81349fd0a68136ed979da610ccdf88175518 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 15:56:45 +0530
+Subject: nvmet-tcp: pass iov_len instead of sg->length to bvec_set_page()
+
+From: Varun Prakash <varun@chelsio.com>
+
+[ Upstream commit 1f0bbf28940cf5edad90ab57b62aa8197bf5e836 ]
+
+iov_len is the valid data length, so pass iov_len instead of sg->length to
+bvec_set_page().
+
+Fixes: 5bfaba275ae6 ("nvmet-tcp: don't map pages which can't come from HIGHMEM")
+Signed-off-by: Rakshana Sridhar <rakshanas@chelsio.com>
+Signed-off-by: Varun Prakash <varun@chelsio.com>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/tcp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
+index c5759eb503d00..5e29da94f72d6 100644
+--- a/drivers/nvme/target/tcp.c
++++ b/drivers/nvme/target/tcp.c
+@@ -321,7 +321,7 @@ static void nvmet_tcp_build_pdu_iovec(struct nvmet_tcp_cmd *cmd)
+ while (length) {
+ u32 iov_len = min_t(u32, length, sg->length - sg_offset);
+
+- bvec_set_page(iov, sg_page(sg), sg->length,
++ bvec_set_page(iov, sg_page(sg), iov_len,
+ sg->offset + sg_offset);
+
+ length -= iov_len;
+--
+2.40.1
+
--- /dev/null
+From 1464ba9834a341ceefa45663ac8a254b09f7dd2a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Feb 2023 16:06:17 +0100
+Subject: nvmet: use bvec_set_page to initialize bvecs
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit fc41c97a3a7b08131e6998bc7692f95729f9d359 ]
+
+Use the bvec_set_page helper to initialize bvecs.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Link: https://lore.kernel.org/r/20230203150634.3199647-7-hch@lst.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: 1f0bbf28940c ("nvmet-tcp: pass iov_len instead of sg->length to bvec_set_page()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/io-cmd-file.c | 10 ++--------
+ drivers/nvme/target/tcp.c | 5 ++---
+ 2 files changed, 4 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/nvme/target/io-cmd-file.c b/drivers/nvme/target/io-cmd-file.c
+index 871c4f32f443f..2d068439b129c 100644
+--- a/drivers/nvme/target/io-cmd-file.c
++++ b/drivers/nvme/target/io-cmd-file.c
+@@ -73,13 +73,6 @@ int nvmet_file_ns_enable(struct nvmet_ns *ns)
+ return ret;
+ }
+
+-static void nvmet_file_init_bvec(struct bio_vec *bv, struct scatterlist *sg)
+-{
+- bv->bv_page = sg_page(sg);
+- bv->bv_offset = sg->offset;
+- bv->bv_len = sg->length;
+-}
+-
+ static ssize_t nvmet_file_submit_bvec(struct nvmet_req *req, loff_t pos,
+ unsigned long nr_segs, size_t count, int ki_flags)
+ {
+@@ -146,7 +139,8 @@ static bool nvmet_file_execute_io(struct nvmet_req *req, int ki_flags)
+
+ memset(&req->f.iocb, 0, sizeof(struct kiocb));
+ for_each_sg(req->sg, sg, req->sg_cnt, i) {
+- nvmet_file_init_bvec(&req->f.bvec[bv_cnt], sg);
++ bvec_set_page(&req->f.bvec[bv_cnt], sg_page(sg), sg->length,
++ sg->offset);
+ len += req->f.bvec[bv_cnt].bv_len;
+ total_len += req->f.bvec[bv_cnt].bv_len;
+ bv_cnt++;
+diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
+index cc05c094de221..c5759eb503d00 100644
+--- a/drivers/nvme/target/tcp.c
++++ b/drivers/nvme/target/tcp.c
+@@ -321,9 +321,8 @@ static void nvmet_tcp_build_pdu_iovec(struct nvmet_tcp_cmd *cmd)
+ while (length) {
+ u32 iov_len = min_t(u32, length, sg->length - sg_offset);
+
+- iov->bv_page = sg_page(sg);
+- iov->bv_len = sg->length;
+- iov->bv_offset = sg->offset + sg_offset;
++ bvec_set_page(iov, sg_page(sg), sg->length,
++ sg->offset + sg_offset);
+
+ length -= iov_len;
+ sg = sg_next(sg);
+--
+2.40.1
+
--- /dev/null
+From 73d216a19041df745d1e948a5bb07769fcfe2e69 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Sep 2023 09:55:39 +0200
+Subject: panic: Reenable preemption in WARN slowpath
+
+From: Lukas Wunner <lukas@wunner.de>
+
+[ Upstream commit cccd32816506cbac3a4c65d9dff51b3125ef1a03 ]
+
+Commit:
+
+ 5a5d7e9badd2 ("cpuidle: lib/bug: Disable rcu_is_watching() during WARN/BUG")
+
+amended warn_slowpath_fmt() to disable preemption until the WARN splat
+has been emitted.
+
+However the commit neglected to reenable preemption in the !fmt codepath,
+i.e. when a WARN splat is emitted without additional format string.
+
+One consequence is that users may see more splats than intended. E.g. a
+WARN splat emitted in a work item results in at least two extra splats:
+
+ BUG: workqueue leaked lock or atomic
+ (emitted by process_one_work())
+
+ BUG: scheduling while atomic
+ (emitted by worker_thread() -> schedule())
+
+Ironically the point of the commit was to *avoid* extra splats. ;)
+
+Fix it.
+
+Fixes: 5a5d7e9badd2 ("cpuidle: lib/bug: Disable rcu_is_watching() during WARN/BUG")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Paul E. McKenney <paulmck@kernel.org>
+Link: https://lore.kernel.org/r/3ec48fde01e4ee6505f77908ba351bad200ae3d1.1694763684.git.lukas@wunner.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/panic.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/kernel/panic.c b/kernel/panic.c
+index ca5452afb456d..63e94f3bd8dcd 100644
+--- a/kernel/panic.c
++++ b/kernel/panic.c
+@@ -695,6 +695,7 @@ void warn_slowpath_fmt(const char *file, int line, unsigned taint,
+ if (!fmt) {
+ __warn(file, line, __builtin_return_address(0), taint,
+ NULL, NULL);
++ warn_rcu_exit(rcu);
+ return;
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 4c7d41ff5c138ae7ea8d4384a5eeb7eb345f8379 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Jul 2023 12:55:01 +0100
+Subject: PCI: dwc: Provide deinit callback for i.MX
+
+From: Mark Brown <broonie@kernel.org>
+
+[ Upstream commit fc8b24c28bec19fc0621d108b9ee81ddfdedb25a ]
+
+The i.MX integration for the DesignWare PCI controller has a _host_exit()
+operation which undoes everything that the _host_init() operation does but
+does not wire this up as the host_deinit callback for the core, or call it
+in any path other than suspend. This means that if we ever unwind the
+initial probe of the device, for example because it fails, the regulator
+core complains that the regulators for the device were left enabled:
+
+imx6q-pcie 33800000.pcie: iATU: unroll T, 4 ob, 4 ib, align 64K, limit 16G
+imx6q-pcie 33800000.pcie: Phy link never came up
+imx6q-pcie 33800000.pcie: Phy link never came up
+imx6q-pcie: probe of 33800000.pcie failed with error -110
+------------[ cut here ]------------
+WARNING: CPU: 2 PID: 46 at drivers/regulator/core.c:2396 _regulator_put+0x110/0x128
+
+Wire up the callback so that the core can clean up after itself.
+
+Link: https://lore.kernel.org/r/20230731-pci-imx-regulator-cleanup-v2-1-fc8fa5c9893d@kernel.org
+Tested-by: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Reviewed-by: Richard Zhu <hongxing.zhu@nxp.com>
+Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pci-imx6.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
+index 47db2d20568ef..388354a8e31cf 100644
+--- a/drivers/pci/controller/dwc/pci-imx6.c
++++ b/drivers/pci/controller/dwc/pci-imx6.c
+@@ -999,6 +999,7 @@ static void imx6_pcie_host_exit(struct dw_pcie_rp *pp)
+
+ static const struct dw_pcie_host_ops imx6_pcie_host_ops = {
+ .host_init = imx6_pcie_host_init,
++ .host_deinit = imx6_pcie_host_exit,
+ };
+
+ static const struct dw_pcie_ops dw_pcie_ops = {
+--
+2.40.1
+
--- /dev/null
+From 2884d6a43a49898db3fa495de5d6032b76ecdfd3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Aug 2023 05:56:21 +0000
+Subject: PCI: fu740: Set the number of MSI vectors
+
+From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
+
+[ Upstream commit 551a60e1225e71fff8efd9390204c505b0870e0f ]
+
+The iMSI-RX module of the DW PCIe controller provides multiple sets of
+MSI_CTRL_INT_i_* registers, and each set is capable of handling 32 MSI
+interrupts. However, the fu740 PCIe controller driver only enabled one set
+of MSI_CTRL_INT_i_* registers, as the total number of supported interrupts
+was not specified.
+
+Set the supported number of MSI vectors to enable all the MSI_CTRL_INT_i_*
+registers on the fu740 PCIe core, allowing the system to fully utilize the
+available MSI interrupts.
+
+Link: https://lore.kernel.org/r/20230807055621.2431-1-yongxuan.wang@sifive.com
+Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-fu740.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pci/controller/dwc/pcie-fu740.c b/drivers/pci/controller/dwc/pcie-fu740.c
+index 0c90583c078bf..1e9b44b8bba48 100644
+--- a/drivers/pci/controller/dwc/pcie-fu740.c
++++ b/drivers/pci/controller/dwc/pcie-fu740.c
+@@ -299,6 +299,7 @@ static int fu740_pcie_probe(struct platform_device *pdev)
+ pci->dev = dev;
+ pci->ops = &dw_pcie_ops;
+ pci->pp.ops = &fu740_pcie_host_ops;
++ pci->pp.num_vectors = MAX_MSI_IRQS;
+
+ /* SiFive specific region: mgmt */
+ afp->mgmt_base = devm_platform_ioremap_resource_byname(pdev, "mgmt");
+--
+2.40.1
+
--- /dev/null
+From 0d824beb0a55a154c469e47a593e2383464ab493 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Aug 2023 17:50:29 -0400
+Subject: PCI: vmd: Disable bridge window for domain reset
+
+From: Nirmal Patel <nirmal.patel@linux.intel.com>
+
+[ Upstream commit f73eedc90bf73d48e8368e6b0b4ad76a7fffaef7 ]
+
+During domain reset process vmd_domain_reset() clears PCI
+configuration space of VMD root ports. But certain platform
+has observed following errors and failed to boot.
+ ...
+ DMAR: VT-d detected Invalidation Queue Error: Reason f
+ DMAR: VT-d detected Invalidation Time-out Error: SID ffff
+ DMAR: VT-d detected Invalidation Completion Error: SID ffff
+ DMAR: QI HEAD: UNKNOWN qw0 = 0x0, qw1 = 0x0
+ DMAR: QI PRIOR: UNKNOWN qw0 = 0x0, qw1 = 0x0
+ DMAR: Invalidation Time-out Error (ITE) cleared
+
+The root cause is that memset_io() clears prefetchable memory base/limit
+registers and prefetchable base/limit 32 bits registers sequentially.
+This seems to be enabling prefetchable memory if the device disabled
+prefetchable memory originally.
+
+Here is an example (before memset_io()):
+
+ PCI configuration space for 10000:00:00.0:
+ 86 80 30 20 06 00 10 00 04 00 04 06 00 00 01 00
+ 00 00 00 00 00 00 00 00 00 01 01 00 00 00 00 20
+ 00 00 00 00 01 00 01 00 ff ff ff ff 75 05 00 00
+ ...
+
+So, prefetchable memory is ffffffff00000000-575000fffff, which is
+disabled. When memset_io() clears prefetchable base 32 bits register,
+the prefetchable memory becomes 0000000000000000-575000fffff, which is
+enabled and incorrect.
+
+Here is the quote from section 7.5.1.3.9 of PCI Express Base 6.0 spec:
+
+ The Prefetchable Memory Limit register must be programmed to a smaller
+ value than the Prefetchable Memory Base register if there is no
+ prefetchable memory on the secondary side of the bridge.
+
+This is believed to be the reason for the failure and in addition the
+sequence of operation in vmd_domain_reset() is not following the PCIe
+specs.
+
+Disable the bridge window by executing a sequence of operations
+borrowed from pci_disable_bridge_window() and pci_setup_bridge_io(),
+that comply with the PCI specifications.
+
+Link: https://lore.kernel.org/r/20230810215029.1177379-1-nirmal.patel@linux.intel.com
+Signed-off-by: Nirmal Patel <nirmal.patel@linux.intel.com>
+Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/vmd.c | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
+index d1eb17e3f1474..d4c9b888a79d7 100644
+--- a/drivers/pci/controller/vmd.c
++++ b/drivers/pci/controller/vmd.c
+@@ -526,8 +526,23 @@ static void vmd_domain_reset(struct vmd_dev *vmd)
+ PCI_CLASS_BRIDGE_PCI))
+ continue;
+
+- memset_io(base + PCI_IO_BASE, 0,
+- PCI_ROM_ADDRESS1 - PCI_IO_BASE);
++ /*
++ * Temporarily disable the I/O range before updating
++ * PCI_IO_BASE.
++ */
++ writel(0x0000ffff, base + PCI_IO_BASE_UPPER16);
++ /* Update lower 16 bits of I/O base/limit */
++ writew(0x00f0, base + PCI_IO_BASE);
++ /* Update upper 16 bits of I/O base/limit */
++ writel(0, base + PCI_IO_BASE_UPPER16);
++
++ /* MMIO Base/Limit */
++ writel(0x0000fff0, base + PCI_MEMORY_BASE);
++
++ /* Prefetchable MMIO Base/Limit */
++ writel(0, base + PCI_PREF_LIMIT_UPPER32);
++ writel(0x0000fff0, base + PCI_PREF_MEMORY_BASE);
++ writel(0xffffffff, base + PCI_PREF_BASE_UPPER32);
+ }
+ }
+ }
+--
+2.40.1
+
--- /dev/null
+From 9b95d1939fa4cfdad52df3b5f37d31da1db6d67b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Aug 2023 09:54:37 +0800
+Subject: perf/imx_ddr: speed up overflow frequency of cycle
+
+From: Xu Yang <xu.yang_2@nxp.com>
+
+[ Upstream commit e89ecd8368860bf05437eabd07d292c316221cfc ]
+
+For i.MX8MP, we cannot ensure that cycle counter overflow occurs at least
+4 times as often as other events. Due to byte counters will count for any
+event configured, it will overflow more often. And if byte counters
+overflow that related counters would stop since they share the
+COUNTER_CNTL. We can speed up cycle counter overflow frequency by setting
+counter parameter (CP) field of cycle counter. In this way, we can avoid
+stop counting byte counters when interrupt didn't come and the byte
+counters can be fetched or updated from each cycle counter overflow
+interrupt.
+
+Because we initialize CP filed to shorten counter0 overflow time, the cycle
+counter will start couting from a fixed/base value each time. We need to
+remove the base from the result too. Therefore, we could get precise result
+from cycle counter.
+
+Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://lore.kernel.org/r/20230811015438.1999307-1-xu.yang_2@nxp.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/perf/fsl_imx8_ddr_perf.c | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c
+index cd4ce2b4906d1..a4cda73b81c9f 100644
+--- a/drivers/perf/fsl_imx8_ddr_perf.c
++++ b/drivers/perf/fsl_imx8_ddr_perf.c
+@@ -28,6 +28,8 @@
+ #define CNTL_CLEAR_MASK 0xFFFFFFFD
+ #define CNTL_OVER_MASK 0xFFFFFFFE
+
++#define CNTL_CP_SHIFT 16
++#define CNTL_CP_MASK (0xFF << CNTL_CP_SHIFT)
+ #define CNTL_CSV_SHIFT 24
+ #define CNTL_CSV_MASK (0xFFU << CNTL_CSV_SHIFT)
+
+@@ -35,6 +37,8 @@
+ #define EVENT_CYCLES_COUNTER 0
+ #define NUM_COUNTERS 4
+
++/* For removing bias if cycle counter CNTL.CP is set to 0xf0 */
++#define CYCLES_COUNTER_MASK 0x0FFFFFFF
+ #define AXI_MASKING_REVERT 0xffff0000 /* AXI_MASKING(MSB 16bits) + AXI_ID(LSB 16bits) */
+
+ #define to_ddr_pmu(p) container_of(p, struct ddr_pmu, pmu)
+@@ -429,6 +433,17 @@ static void ddr_perf_counter_enable(struct ddr_pmu *pmu, int config,
+ writel(0, pmu->base + reg);
+ val = CNTL_EN | CNTL_CLEAR;
+ val |= FIELD_PREP(CNTL_CSV_MASK, config);
++
++ /*
++ * On i.MX8MP we need to bias the cycle counter to overflow more often.
++ * We do this by initializing bits [23:16] of the counter value via the
++ * COUNTER_CTRL Counter Parameter (CP) field.
++ */
++ if (pmu->devtype_data->quirks & DDR_CAP_AXI_ID_FILTER_ENHANCED) {
++ if (counter == EVENT_CYCLES_COUNTER)
++ val |= FIELD_PREP(CNTL_CP_MASK, 0xf0);
++ }
++
+ writel(val, pmu->base + reg);
+ } else {
+ /* Disable counter */
+@@ -468,6 +483,12 @@ static void ddr_perf_event_update(struct perf_event *event)
+ int ret;
+
+ new_raw_count = ddr_perf_read_counter(pmu, counter);
++ /* Remove the bias applied in ddr_perf_counter_enable(). */
++ if (pmu->devtype_data->quirks & DDR_CAP_AXI_ID_FILTER_ENHANCED) {
++ if (counter == EVENT_CYCLES_COUNTER)
++ new_raw_count &= CYCLES_COUNTER_MASK;
++ }
++
+ local64_add(new_raw_count, &event->count);
+
+ /*
+--
+2.40.1
+
--- /dev/null
+From 6a0bfb3e70a8e396f5271060cf644c58beb91863 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Aug 2023 20:40:12 +0800
+Subject: perf/smmuv3: Enable HiSilicon Erratum 162001900 quirk for HIP08/09
+
+From: Yicong Yang <yangyicong@hisilicon.com>
+
+[ Upstream commit 0242737dc4eb9f6e9a5ea594b3f93efa0b12f28d ]
+
+Some HiSilicon SMMU PMCG suffers the erratum 162001900 that the PMU
+disable control sometimes fail to disable the counters. This will lead
+to error or inaccurate data since before we enable the counters the
+counter's still counting for the event used in last perf session.
+
+This patch tries to fix this by hardening the global disable process.
+Before disable the PMU, writing an invalid event type (0xffff) to
+focibly stop the counters. Correspondingly restore each events on
+pmu::pmu_enable().
+
+Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
+Link: https://lore.kernel.org/r/20230814124012.58013-1-yangyicong@huawei.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/arm64/silicon-errata.rst | 3 ++
+ drivers/acpi/arm64/iort.c | 5 ++-
+ drivers/perf/arm_smmuv3_pmu.c | 46 +++++++++++++++++++++++++-
+ include/linux/acpi_iort.h | 1 +
+ 4 files changed, 53 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
+index b3c8ac6a2c385..9000640f7f7a0 100644
+--- a/Documentation/arm64/silicon-errata.rst
++++ b/Documentation/arm64/silicon-errata.rst
+@@ -193,6 +193,9 @@ stable kernels.
+ +----------------+-----------------+-----------------+-----------------------------+
+ | Hisilicon | Hip08 SMMU PMCG | #162001800 | N/A |
+ +----------------+-----------------+-----------------+-----------------------------+
++| Hisilicon | Hip08 SMMU PMCG | #162001900 | N/A |
++| | Hip09 SMMU PMCG | | |
+++----------------+-----------------+-----------------+-----------------------------+
+ +----------------+-----------------+-----------------+-----------------------------+
+ | Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 |
+ +----------------+-----------------+-----------------+-----------------------------+
+diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
+index 2e1cae53536f5..3a6cf5675e607 100644
+--- a/drivers/acpi/arm64/iort.c
++++ b/drivers/acpi/arm64/iort.c
+@@ -1699,7 +1699,10 @@ static void __init arm_smmu_v3_pmcg_init_resources(struct resource *res,
+ static struct acpi_platform_list pmcg_plat_info[] __initdata = {
+ /* HiSilicon Hip08 Platform */
+ {"HISI ", "HIP08 ", 0, ACPI_SIG_IORT, greater_than_or_equal,
+- "Erratum #162001800", IORT_SMMU_V3_PMCG_HISI_HIP08},
++ "Erratum #162001800, Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP08},
++ /* HiSilicon Hip09 Platform */
++ {"HISI ", "HIP09 ", 0, ACPI_SIG_IORT, greater_than_or_equal,
++ "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
+ { }
+ };
+
+diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
+index 25a269d431e45..0e17c57ddb876 100644
+--- a/drivers/perf/arm_smmuv3_pmu.c
++++ b/drivers/perf/arm_smmuv3_pmu.c
+@@ -115,6 +115,7 @@
+ #define SMMU_PMCG_PA_SHIFT 12
+
+ #define SMMU_PMCG_EVCNTR_RDONLY BIT(0)
++#define SMMU_PMCG_HARDEN_DISABLE BIT(1)
+
+ static int cpuhp_state_num;
+
+@@ -159,6 +160,20 @@ static inline void smmu_pmu_enable(struct pmu *pmu)
+ writel(SMMU_PMCG_CR_ENABLE, smmu_pmu->reg_base + SMMU_PMCG_CR);
+ }
+
++static int smmu_pmu_apply_event_filter(struct smmu_pmu *smmu_pmu,
++ struct perf_event *event, int idx);
++
++static inline void smmu_pmu_enable_quirk_hip08_09(struct pmu *pmu)
++{
++ struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu);
++ unsigned int idx;
++
++ for_each_set_bit(idx, smmu_pmu->used_counters, smmu_pmu->num_counters)
++ smmu_pmu_apply_event_filter(smmu_pmu, smmu_pmu->events[idx], idx);
++
++ smmu_pmu_enable(pmu);
++}
++
+ static inline void smmu_pmu_disable(struct pmu *pmu)
+ {
+ struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu);
+@@ -167,6 +182,22 @@ static inline void smmu_pmu_disable(struct pmu *pmu)
+ writel(0, smmu_pmu->reg_base + SMMU_PMCG_IRQ_CTRL);
+ }
+
++static inline void smmu_pmu_disable_quirk_hip08_09(struct pmu *pmu)
++{
++ struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu);
++ unsigned int idx;
++
++ /*
++ * The global disable of PMU sometimes fail to stop the counting.
++ * Harden this by writing an invalid event type to each used counter
++ * to forcibly stop counting.
++ */
++ for_each_set_bit(idx, smmu_pmu->used_counters, smmu_pmu->num_counters)
++ writel(0xffff, smmu_pmu->reg_base + SMMU_PMCG_EVTYPER(idx));
++
++ smmu_pmu_disable(pmu);
++}
++
+ static inline void smmu_pmu_counter_set_value(struct smmu_pmu *smmu_pmu,
+ u32 idx, u64 value)
+ {
+@@ -765,7 +796,10 @@ static void smmu_pmu_get_acpi_options(struct smmu_pmu *smmu_pmu)
+ switch (model) {
+ case IORT_SMMU_V3_PMCG_HISI_HIP08:
+ /* HiSilicon Erratum 162001800 */
+- smmu_pmu->options |= SMMU_PMCG_EVCNTR_RDONLY;
++ smmu_pmu->options |= SMMU_PMCG_EVCNTR_RDONLY | SMMU_PMCG_HARDEN_DISABLE;
++ break;
++ case IORT_SMMU_V3_PMCG_HISI_HIP09:
++ smmu_pmu->options |= SMMU_PMCG_HARDEN_DISABLE;
+ break;
+ }
+
+@@ -890,6 +924,16 @@ static int smmu_pmu_probe(struct platform_device *pdev)
+ if (!dev->of_node)
+ smmu_pmu_get_acpi_options(smmu_pmu);
+
++ /*
++ * For platforms suffer this quirk, the PMU disable sometimes fails to
++ * stop the counters. This will leads to inaccurate or error counting.
++ * Forcibly disable the counters with these quirk handler.
++ */
++ if (smmu_pmu->options & SMMU_PMCG_HARDEN_DISABLE) {
++ smmu_pmu->pmu.pmu_enable = smmu_pmu_enable_quirk_hip08_09;
++ smmu_pmu->pmu.pmu_disable = smmu_pmu_disable_quirk_hip08_09;
++ }
++
+ /* Pick one CPU to be the preferred one to use */
+ smmu_pmu->on_cpu = raw_smp_processor_id();
+ WARN_ON(irq_set_affinity(smmu_pmu->irq, cpumask_of(smmu_pmu->on_cpu)));
+diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
+index b43be0987b19e..a2a51fafa3550 100644
+--- a/include/linux/acpi_iort.h
++++ b/include/linux/acpi_iort.h
+@@ -21,6 +21,7 @@
+ */
+ #define IORT_SMMU_V3_PMCG_GENERIC 0x00000000 /* Generic SMMUv3 PMCG */
+ #define IORT_SMMU_V3_PMCG_HISI_HIP08 0x00000001 /* HiSilicon HIP08 PMCG */
++#define IORT_SMMU_V3_PMCG_HISI_HIP09 0x00000002 /* HiSilicon HIP09 PMCG */
+
+ int iort_register_domain_token(int trans_id, phys_addr_t base,
+ struct fwnode_handle *fw_node);
+--
+2.40.1
+
--- /dev/null
+From fc821297ed7d38af28a509ff73be78d58fbffa2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Nov 2022 09:19:29 +0800
+Subject: powerpc/pseries: fix possible memory leak in ibmebus_bus_init()
+
+From: ruanjinjie <ruanjinjie@huawei.com>
+
+[ Upstream commit afda85b963c12947e298ad85d757e333aa40fd74 ]
+
+If device_register() returns error in ibmebus_bus_init(), 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: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20221110011929.3709774-1-ruanjinjie@huawei.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/platforms/pseries/ibmebus.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c
+index a870cada7acd2..ed5fc70b7353a 100644
+--- a/arch/powerpc/platforms/pseries/ibmebus.c
++++ b/arch/powerpc/platforms/pseries/ibmebus.c
+@@ -455,6 +455,7 @@ static int __init ibmebus_bus_init(void)
+ if (err) {
+ printk(KERN_WARNING "%s: device_register returned %i\n",
+ __func__, err);
++ put_device(&ibmebus_bus_device);
+ bus_unregister(&ibmebus_bus_type);
+
+ return err;
+--
+2.40.1
+
--- /dev/null
+From a1097fe528c058e23ee8c05b5e54328a253ea81a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 21:52:05 +0206
+Subject: printk: Consolidate console deferred printing
+
+From: John Ogness <john.ogness@linutronix.de>
+
+[ Upstream commit 696ffaf50e1f8dbc66223ff614473f945f5fb8d8 ]
+
+Printing to consoles can be deferred for several reasons:
+
+- explicitly with printk_deferred()
+- printk() in NMI context
+- recursive printk() calls
+
+The current implementation is not consistent. For printk_deferred(),
+irq work is scheduled twice. For NMI und recursive, panic CPU
+suppression and caller delays are not properly enforced.
+
+Correct these inconsistencies by consolidating the deferred printing
+code so that vprintk_deferred() is the top-level function for
+deferred printing and vprintk_emit() will perform whichever irq_work
+queueing is appropriate.
+
+Also add kerneldoc for wake_up_klogd() and defer_console_output() to
+clarify their differences and appropriate usage.
+
+Signed-off-by: John Ogness <john.ogness@linutronix.de>
+Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Reviewed-by: Petr Mladek <pmladek@suse.com>
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Link: https://lore.kernel.org/r/20230717194607.145135-6-john.ogness@linutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/printk/printk.c | 35 ++++++++++++++++++++++++++++-------
+ kernel/printk/printk_safe.c | 9 ++-------
+ 2 files changed, 30 insertions(+), 14 deletions(-)
+
+diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
+index 4b9429f3fd6d8..cc53fb77f77cc 100644
+--- a/kernel/printk/printk.c
++++ b/kernel/printk/printk.c
+@@ -2269,7 +2269,11 @@ asmlinkage int vprintk_emit(int facility, int level,
+ preempt_enable();
+ }
+
+- wake_up_klogd();
++ if (in_sched)
++ defer_console_output();
++ else
++ wake_up_klogd();
++
+ return printed_len;
+ }
+ EXPORT_SYMBOL(vprintk_emit);
+@@ -3490,11 +3494,33 @@ static void __wake_up_klogd(int val)
+ preempt_enable();
+ }
+
++/**
++ * wake_up_klogd - Wake kernel logging daemon
++ *
++ * Use this function when new records have been added to the ringbuffer
++ * and the console printing of those records has already occurred or is
++ * known to be handled by some other context. This function will only
++ * wake the logging daemon.
++ *
++ * Context: Any context.
++ */
+ void wake_up_klogd(void)
+ {
+ __wake_up_klogd(PRINTK_PENDING_WAKEUP);
+ }
+
++/**
++ * defer_console_output - Wake kernel logging daemon and trigger
++ * console printing in a deferred context
++ *
++ * Use this function when new records have been added to the ringbuffer,
++ * this context is responsible for console printing those records, but
++ * the current context is not allowed to perform the console printing.
++ * Trigger an irq_work context to perform the console printing. This
++ * function also wakes the logging daemon.
++ *
++ * Context: Any context.
++ */
+ void defer_console_output(void)
+ {
+ /*
+@@ -3511,12 +3537,7 @@ void printk_trigger_flush(void)
+
+ int vprintk_deferred(const char *fmt, va_list args)
+ {
+- int r;
+-
+- r = vprintk_emit(0, LOGLEVEL_SCHED, NULL, fmt, args);
+- defer_console_output();
+-
+- return r;
++ return vprintk_emit(0, LOGLEVEL_SCHED, NULL, fmt, args);
+ }
+
+ int _printk_deferred(const char *fmt, ...)
+diff --git a/kernel/printk/printk_safe.c b/kernel/printk/printk_safe.c
+index ef0f9a2044da1..6d10927a07d83 100644
+--- a/kernel/printk/printk_safe.c
++++ b/kernel/printk/printk_safe.c
+@@ -38,13 +38,8 @@ asmlinkage int vprintk(const char *fmt, va_list args)
+ * Use the main logbuf even in NMI. But avoid calling console
+ * drivers that might have their own locks.
+ */
+- if (this_cpu_read(printk_context) || in_nmi()) {
+- int len;
+-
+- len = vprintk_store(0, LOGLEVEL_DEFAULT, NULL, fmt, args);
+- defer_console_output();
+- return len;
+- }
++ if (this_cpu_read(printk_context) || in_nmi())
++ return vprintk_deferred(fmt, args);
+
+ /* No obstacles. */
+ return vprintk_default(fmt, args);
+--
+2.40.1
+
--- /dev/null
+From bf2b06a8d40d573e7b6d08c86ce8635b9e2554c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Jul 2023 21:52:03 +0206
+Subject: printk: Keep non-panic-CPUs out of console lock
+
+From: John Ogness <john.ogness@linutronix.de>
+
+[ Upstream commit 51a1d258e50e03a0216bf42b6af9ff34ec402ac1 ]
+
+When in a panic situation, non-panic CPUs should avoid holding the
+console lock so as not to contend with the panic CPU. This is already
+implemented with abandon_console_lock_in_panic(), which is checked
+after each printed line. However, non-panic CPUs should also avoid
+trying to acquire the console lock during a panic.
+
+Modify console_trylock() to fail and console_lock() to block() when
+called from a non-panic CPU during a panic.
+
+Signed-off-by: John Ogness <john.ogness@linutronix.de>
+Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Reviewed-by: Petr Mladek <pmladek@suse.com>
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Link: https://lore.kernel.org/r/20230717194607.145135-4-john.ogness@linutronix.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/printk/printk.c | 45 ++++++++++++++++++++++++------------------
+ 1 file changed, 26 insertions(+), 19 deletions(-)
+
+diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
+index e4f1e7478b521..4b9429f3fd6d8 100644
+--- a/kernel/printk/printk.c
++++ b/kernel/printk/printk.c
+@@ -2552,6 +2552,25 @@ static int console_cpu_notify(unsigned int cpu)
+ return 0;
+ }
+
++/*
++ * Return true when this CPU should unlock console_sem without pushing all
++ * messages to the console. This reduces the chance that the console is
++ * locked when the panic CPU tries to use it.
++ */
++static bool abandon_console_lock_in_panic(void)
++{
++ if (!panic_in_progress())
++ return false;
++
++ /*
++ * We can use raw_smp_processor_id() here because it is impossible for
++ * the task to be migrated to the panic_cpu, or away from it. If
++ * panic_cpu has already been set, and we're not currently executing on
++ * that CPU, then we never will be.
++ */
++ return atomic_read(&panic_cpu) != raw_smp_processor_id();
++}
++
+ /**
+ * console_lock - lock the console system for exclusive use.
+ *
+@@ -2564,6 +2583,10 @@ void console_lock(void)
+ {
+ might_sleep();
+
++ /* On panic, the console_lock must be left to the panic cpu. */
++ while (abandon_console_lock_in_panic())
++ msleep(1000);
++
+ down_console_sem();
+ if (console_suspended)
+ return;
+@@ -2582,6 +2605,9 @@ EXPORT_SYMBOL(console_lock);
+ */
+ int console_trylock(void)
+ {
++ /* On panic, the console_lock must be left to the panic cpu. */
++ if (abandon_console_lock_in_panic())
++ return 0;
+ if (down_trylock_console_sem())
+ return 0;
+ if (console_suspended) {
+@@ -2600,25 +2626,6 @@ int is_console_locked(void)
+ }
+ EXPORT_SYMBOL(is_console_locked);
+
+-/*
+- * Return true when this CPU should unlock console_sem without pushing all
+- * messages to the console. This reduces the chance that the console is
+- * locked when the panic CPU tries to use it.
+- */
+-static bool abandon_console_lock_in_panic(void)
+-{
+- if (!panic_in_progress())
+- return false;
+-
+- /*
+- * We can use raw_smp_processor_id() here because it is impossible for
+- * the task to be migrated to the panic_cpu, or away from it. If
+- * panic_cpu has already been set, and we're not currently executing on
+- * that CPU, then we never will be.
+- */
+- return atomic_read(&panic_cpu) != raw_smp_processor_id();
+-}
+-
+ /*
+ * Check if the given console is currently capable and allowed to print
+ * records.
+--
+2.40.1
+
--- /dev/null
+From bf579feb09d230cb9becbd852d4ed9af9f21bc0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 15:39:26 +0800
+Subject: rcuscale: Move rcu_scale_writer() schedule_timeout_uninterruptible()
+ to _idle()
+
+From: Zqiang <qiang.zhang1211@gmail.com>
+
+[ Upstream commit e60c122a1614b4f65b29a7bef9d83b9fd30e937a ]
+
+The rcuscale.holdoff module parameter can be used to delay the start
+of rcu_scale_writer() kthread. However, the hung-task timeout will
+trigger when the timeout specified by rcuscale.holdoff is greater than
+hung_task_timeout_secs:
+
+runqemu kvm nographic slirp qemuparams="-smp 4 -m 2048M"
+bootparams="rcuscale.shutdown=0 rcuscale.holdoff=300"
+
+[ 247.071753] INFO: task rcu_scale_write:59 blocked for more than 122 seconds.
+[ 247.072529] Not tainted 6.4.0-rc1-00134-gb9ed6de8d4ff #7
+[ 247.073400] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+[ 247.074331] task:rcu_scale_write state:D stack:30144 pid:59 ppid:2 flags:0x00004000
+[ 247.075346] Call Trace:
+[ 247.075660] <TASK>
+[ 247.075965] __schedule+0x635/0x1280
+[ 247.076448] ? __pfx___schedule+0x10/0x10
+[ 247.076967] ? schedule_timeout+0x2dc/0x4d0
+[ 247.077471] ? __pfx_lock_release+0x10/0x10
+[ 247.078018] ? enqueue_timer+0xe2/0x220
+[ 247.078522] schedule+0x84/0x120
+[ 247.078957] schedule_timeout+0x2e1/0x4d0
+[ 247.079447] ? __pfx_schedule_timeout+0x10/0x10
+[ 247.080032] ? __pfx_rcu_scale_writer+0x10/0x10
+[ 247.080591] ? __pfx_process_timeout+0x10/0x10
+[ 247.081163] ? __pfx_sched_set_fifo_low+0x10/0x10
+[ 247.081760] ? __pfx_rcu_scale_writer+0x10/0x10
+[ 247.082287] rcu_scale_writer+0x6b1/0x7f0
+[ 247.082773] ? mark_held_locks+0x29/0xa0
+[ 247.083252] ? __pfx_rcu_scale_writer+0x10/0x10
+[ 247.083865] ? __pfx_rcu_scale_writer+0x10/0x10
+[ 247.084412] kthread+0x179/0x1c0
+[ 247.084759] ? __pfx_kthread+0x10/0x10
+[ 247.085098] ret_from_fork+0x2c/0x50
+[ 247.085433] </TASK>
+
+This commit therefore replaces schedule_timeout_uninterruptible() with
+schedule_timeout_idle().
+
+Signed-off-by: Zqiang <qiang.zhang1211@gmail.com>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/rcu/rcuscale.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c
+index 7854dc3226e1b..0b88d96511adc 100644
+--- a/kernel/rcu/rcuscale.c
++++ b/kernel/rcu/rcuscale.c
+@@ -423,7 +423,7 @@ rcu_scale_writer(void *arg)
+ sched_set_fifo_low(current);
+
+ if (holdoff)
+- schedule_timeout_uninterruptible(holdoff * HZ);
++ schedule_timeout_idle(holdoff * HZ);
+
+ /*
+ * Wait until rcu_end_inkernel_boot() is called for normal GP tests
+--
+2.40.1
+
--- /dev/null
+From 740645dffb8d9d7ac85af7d011837b9d3cfb37a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Sep 2023 17:58:17 +0800
+Subject: riscv: kexec: Align the kexeced kernel entry
+
+From: Song Shuai <songshuaishuai@tinylab.org>
+
+[ Upstream commit 1bfb2b618d52e59a4ef1896b46c4698ad2be66b7 ]
+
+The current riscv boot protocol requires 2MB alignment for RV64
+and 4MB alignment for RV32.
+
+In KEXEC_FILE path, the elf_find_pbase() function should align
+the kexeced kernel entry according to the requirement, otherwise
+the kexeced kernel would silently BUG at the setup_vm().
+
+Fixes: 8acea455fafa ("RISC-V: Support for kexec_file on panic")
+Signed-off-by: Song Shuai <songshuaishuai@tinylab.org>
+Link: https://lore.kernel.org/r/20230906095817.364390-1-songshuaishuai@tinylab.org
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/elf_kexec.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/arch/riscv/kernel/elf_kexec.c b/arch/riscv/kernel/elf_kexec.c
+index c08bb5c3b3857..b3b96ff46d193 100644
+--- a/arch/riscv/kernel/elf_kexec.c
++++ b/arch/riscv/kernel/elf_kexec.c
+@@ -98,7 +98,13 @@ static int elf_find_pbase(struct kimage *image, unsigned long kernel_len,
+ kbuf.image = image;
+ kbuf.buf_min = lowest_paddr;
+ kbuf.buf_max = ULONG_MAX;
+- kbuf.buf_align = PAGE_SIZE;
++
++ /*
++ * Current riscv boot protocol requires 2MB alignment for
++ * RV64 and 4MB alignment for RV32
++ *
++ */
++ kbuf.buf_align = PMD_SIZE;
+ kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
+ kbuf.memsz = ALIGN(kernel_len, PAGE_SIZE);
+ kbuf.top_down = false;
+--
+2.40.1
+
--- /dev/null
+From e5edb399420ca00f9b914e6af64b456b79181812 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 10:25:36 +0200
+Subject: samples/hw_breakpoint: fix building without module unloading
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit b9080468caeddc58a91edd1c3a7d212ea82b0d1d ]
+
+__symbol_put() is really meant as an internal helper and is not available
+when module unloading is disabled, unlike the previously used symbol_put():
+
+samples/hw_breakpoint/data_breakpoint.c: In function 'hw_break_module_exit':
+samples/hw_breakpoint/data_breakpoint.c:73:9: error: implicit declaration of function '__symbol_put'; did you mean '__symbol_get'? [-Werror=implicit-function-declaration]
+
+The hw_break_module_exit() function is not actually used when module
+unloading is disabled, but it still causes the build failure for an
+undefined identifier. Enclose this one call in an appropriate #ifdef to
+clarify what the requirement is. Leaving out the entire exit function
+would also work but feels less clar in this case.
+
+Fixes: 910e230d5f1bb ("samples/hw_breakpoint: Fix kernel BUG 'invalid opcode: 0000'")
+Fixes: d8a84d33a4954 ("samples/hw_breakpoint: drop use of kallsyms_lookup_name()")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Petr Mladek <pmladek@suse.com>
+Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ samples/hw_breakpoint/data_breakpoint.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/samples/hw_breakpoint/data_breakpoint.c b/samples/hw_breakpoint/data_breakpoint.c
+index 9debd128b2ab8..b99322f188e59 100644
+--- a/samples/hw_breakpoint/data_breakpoint.c
++++ b/samples/hw_breakpoint/data_breakpoint.c
+@@ -70,7 +70,9 @@ static int __init hw_break_module_init(void)
+ static void __exit hw_break_module_exit(void)
+ {
+ unregister_wide_hw_breakpoint(sample_hbp);
++#ifdef CONFIG_MODULE_UNLOAD
+ __symbol_put(ksym_name);
++#endif
+ printk(KERN_INFO "HW Breakpoint for %s write uninstalled\n", ksym_name);
+ }
+
+--
+2.40.1
+
--- /dev/null
+From 0b3e71168d6dd828f91f00ddc5b397e53cb76967 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Apr 2023 23:05:17 +0800
+Subject: samples/hw_breakpoint: Fix kernel BUG 'invalid opcode: 0000'
+
+From: Rong Tao <rongtao@cestc.cn>
+
+[ Upstream commit 910e230d5f1bb72c54532e94fbb1705095c7bab6 ]
+
+Macro symbol_put() is defined as __symbol_put(__stringify(x))
+
+ ksym_name = "jiffies"
+ symbol_put(ksym_name)
+
+will be resolved as
+
+ __symbol_put("ksym_name")
+
+which is clearly wrong. So symbol_put must be replaced with __symbol_put.
+
+When we uninstall hw_breakpoint.ko (rmmod), a kernel bug occurs with the
+following error:
+
+[11381.854152] kernel BUG at kernel/module/main.c:779!
+[11381.854159] invalid opcode: 0000 [#2] PREEMPT SMP PTI
+[11381.854163] CPU: 8 PID: 59623 Comm: rmmod Tainted: G D OE 6.2.9-200.fc37.x86_64 #1
+[11381.854167] Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./B360M-HDV, BIOS P3.20 10/23/2018
+[11381.854169] RIP: 0010:__symbol_put+0xa2/0xb0
+[11381.854175] Code: 00 e8 92 d2 f7 ff 65 8b 05 c3 2f e6 78 85 c0 74 1b 48 8b 44 24 30 65 48 2b 04 25 28 00 00 00 75 12 48 83 c4 38 c3 cc cc cc cc <0f> 0b 0f 1f 44 00 00 eb de e8 c0 df d8 00 90 90 90 90 90 90 90 90
+[11381.854178] RSP: 0018:ffffad8ec6ae7dd0 EFLAGS: 00010246
+[11381.854181] RAX: 0000000000000000 RBX: ffffffffc1fd1240 RCX: 000000000000000c
+[11381.854184] RDX: 000000000000006b RSI: ffffffffc02bf7c7 RDI: ffffffffc1fd001c
+[11381.854186] RBP: 000055a38b76e7c8 R08: ffffffff871ccfe0 R09: 0000000000000000
+[11381.854188] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
+[11381.854190] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
+[11381.854192] FS: 00007fbf7c62c740(0000) GS:ffff8c5badc00000(0000) knlGS:0000000000000000
+[11381.854195] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[11381.854197] CR2: 000055a38b7793f8 CR3: 0000000363e1e001 CR4: 00000000003726e0
+[11381.854200] DR0: ffffffffb3407980 DR1: 0000000000000000 DR2: 0000000000000000
+[11381.854202] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
+[11381.854204] Call Trace:
+[11381.854207] <TASK>
+[11381.854212] s_module_exit+0xc/0xff0 [symbol_getput]
+[11381.854219] __do_sys_delete_module.constprop.0+0x198/0x2f0
+[11381.854225] do_syscall_64+0x58/0x80
+[11381.854231] ? exit_to_user_mode_prepare+0x180/0x1f0
+[11381.854237] ? syscall_exit_to_user_mode+0x17/0x40
+[11381.854241] ? do_syscall_64+0x67/0x80
+[11381.854245] ? syscall_exit_to_user_mode+0x17/0x40
+[11381.854248] ? do_syscall_64+0x67/0x80
+[11381.854252] ? exc_page_fault+0x70/0x170
+[11381.854256] entry_SYSCALL_64_after_hwframe+0x72/0xdc
+
+Signed-off-by: Rong Tao <rongtao@cestc.cn>
+Reviewed-by: Petr Mladek <pmladek@suse.com>
+Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ samples/hw_breakpoint/data_breakpoint.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/samples/hw_breakpoint/data_breakpoint.c b/samples/hw_breakpoint/data_breakpoint.c
+index 418c46fe5ffc3..9debd128b2ab8 100644
+--- a/samples/hw_breakpoint/data_breakpoint.c
++++ b/samples/hw_breakpoint/data_breakpoint.c
+@@ -70,7 +70,7 @@ static int __init hw_break_module_init(void)
+ static void __exit hw_break_module_exit(void)
+ {
+ unregister_wide_hw_breakpoint(sample_hbp);
+- symbol_put(ksym_name);
++ __symbol_put(ksym_name);
+ printk(KERN_INFO "HW Breakpoint for %s write uninstalled\n", ksym_name);
+ }
+
+--
+2.40.1
+
--- /dev/null
+From e7e424c0d8be3041a4e19dcba86d37ec0f72c2df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 May 2023 19:00:10 -0700
+Subject: scftorture: Forgive memory-allocation failure if KASAN
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ Upstream commit 013608cd0812bdb21fc26d39ed8fdd2fc76e8b9b ]
+
+Kernels built with CONFIG_KASAN=y quarantine newly freed memory in order
+to better detect use-after-free errors. However, this can exhaust memory
+more quickly in allocator-heavy tests, which can result in spurious
+scftorture failure. This commit therefore forgives memory-allocation
+failure in kernels built with CONFIG_KASAN=y, but continues counting
+the errors for use in detailed test-result analyses.
+
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/scftorture.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/scftorture.c b/kernel/scftorture.c
+index 5d113aa59e773..83c33ba0ca7e0 100644
+--- a/kernel/scftorture.c
++++ b/kernel/scftorture.c
+@@ -171,7 +171,8 @@ static void scf_torture_stats_print(void)
+ scfs.n_all_wait += scf_stats_p[i].n_all_wait;
+ }
+ if (atomic_read(&n_errs) || atomic_read(&n_mb_in_errs) ||
+- atomic_read(&n_mb_out_errs) || atomic_read(&n_alloc_errs))
++ atomic_read(&n_mb_out_errs) ||
++ (!IS_ENABLED(CONFIG_KASAN) && atomic_read(&n_alloc_errs)))
+ bangstr = "!!! ";
+ pr_alert("%s %sscf_invoked_count %s: %lld resched: %lld single: %lld/%lld single_ofl: %lld/%lld single_rpc: %lld single_rpc_ofl: %lld many: %lld/%lld all: %lld/%lld ",
+ SCFTORT_FLAG, bangstr, isdone ? "VER" : "ver", invoked_count, scfs.n_resched,
+@@ -323,7 +324,8 @@ static void scftorture_invoke_one(struct scf_statistics *scfp, struct torture_ra
+ preempt_disable();
+ if (scfsp->scfs_prim == SCF_PRIM_SINGLE || scfsp->scfs_wait) {
+ scfcp = kmalloc(sizeof(*scfcp), GFP_ATOMIC);
+- if (WARN_ON_ONCE(!scfcp)) {
++ if (!scfcp) {
++ WARN_ON_ONCE(!IS_ENABLED(CONFIG_KASAN));
+ atomic_inc(&n_alloc_errs);
+ } else {
+ scfcp->scfc_cpu = -1;
+--
+2.40.1
+
--- /dev/null
+From 085af860ae8437a78bab2af15ea3c93ec3de4b3c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jul 2023 11:05:18 -0700
+Subject: scsi: lpfc: Abort outstanding ELS cmds when mailbox timeout error is
+ detected
+
+From: Justin Tee <justin.tee@broadcom.com>
+
+[ Upstream commit 089ea22e374aa20043e72243c47b5867d5419d38 ]
+
+A mailbox timeout error usually indicates something has gone wrong, and a
+follow up reset of the HBA is a typical recovery mechanism. Introduce a
+MBX_TMO_ERR flag to detect such cases and have lpfc_els_flush_cmd abort ELS
+commands if the MBX_TMO_ERR flag condition was set. This ensures all of
+the registered SGL resources meant for ELS traffic are not leaked after an
+HBA reset.
+
+Signed-off-by: Justin Tee <justin.tee@broadcom.com>
+Link: https://lore.kernel.org/r/20230712180522.112722-9-justintee8345@gmail.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc.h | 1 +
+ drivers/scsi/lpfc/lpfc_els.c | 25 ++++++++++++++++++-------
+ drivers/scsi/lpfc/lpfc_init.c | 20 +++++++++++++++++---
+ drivers/scsi/lpfc/lpfc_sli.c | 8 +++++++-
+ 4 files changed, 43 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
+index 9ad233b40a9e2..664ac3069c4be 100644
+--- a/drivers/scsi/lpfc/lpfc.h
++++ b/drivers/scsi/lpfc/lpfc.h
+@@ -895,6 +895,7 @@ enum lpfc_irq_chann_mode {
+ enum lpfc_hba_bit_flags {
+ FABRIC_COMANDS_BLOCKED,
+ HBA_PCI_ERR,
++ MBX_TMO_ERR,
+ };
+
+ struct lpfc_hba {
+diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
+index 43ebb41ded593..6b5ce9869e6b4 100644
+--- a/drivers/scsi/lpfc/lpfc_els.c
++++ b/drivers/scsi/lpfc/lpfc_els.c
+@@ -9410,11 +9410,13 @@ void
+ lpfc_els_flush_cmd(struct lpfc_vport *vport)
+ {
+ LIST_HEAD(abort_list);
++ LIST_HEAD(cancel_list);
+ struct lpfc_hba *phba = vport->phba;
+ struct lpfc_sli_ring *pring;
+ struct lpfc_iocbq *tmp_iocb, *piocb;
+ u32 ulp_command;
+ unsigned long iflags = 0;
++ bool mbx_tmo_err;
+
+ lpfc_fabric_abort_vport(vport);
+
+@@ -9436,15 +9438,16 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport)
+ if (phba->sli_rev == LPFC_SLI_REV4)
+ spin_lock(&pring->ring_lock);
+
++ mbx_tmo_err = test_bit(MBX_TMO_ERR, &phba->bit_flags);
+ /* First we need to issue aborts to outstanding cmds on txcmpl */
+ list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
+- if (piocb->cmd_flag & LPFC_IO_LIBDFC)
++ if (piocb->cmd_flag & LPFC_IO_LIBDFC && !mbx_tmo_err)
+ continue;
+
+ if (piocb->vport != vport)
+ continue;
+
+- if (piocb->cmd_flag & LPFC_DRIVER_ABORTED)
++ if (piocb->cmd_flag & LPFC_DRIVER_ABORTED && !mbx_tmo_err)
+ continue;
+
+ /* On the ELS ring we can have ELS_REQUESTs or
+@@ -9463,8 +9466,8 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport)
+ */
+ if (phba->link_state == LPFC_LINK_DOWN)
+ piocb->cmd_cmpl = lpfc_cmpl_els_link_down;
+- }
+- if (ulp_command == CMD_GEN_REQUEST64_CR)
++ } else if (ulp_command == CMD_GEN_REQUEST64_CR ||
++ mbx_tmo_err)
+ list_add_tail(&piocb->dlist, &abort_list);
+ }
+
+@@ -9476,11 +9479,19 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport)
+ list_for_each_entry_safe(piocb, tmp_iocb, &abort_list, dlist) {
+ spin_lock_irqsave(&phba->hbalock, iflags);
+ list_del_init(&piocb->dlist);
+- lpfc_sli_issue_abort_iotag(phba, pring, piocb, NULL);
++ if (mbx_tmo_err)
++ list_move_tail(&piocb->list, &cancel_list);
++ else
++ lpfc_sli_issue_abort_iotag(phba, pring, piocb, NULL);
++
+ spin_unlock_irqrestore(&phba->hbalock, iflags);
+ }
+- /* Make sure HBA is alive */
+- lpfc_issue_hb_tmo(phba);
++ if (!list_empty(&cancel_list))
++ lpfc_sli_cancel_iocbs(phba, &cancel_list, IOSTAT_LOCAL_REJECT,
++ IOERR_SLI_ABORTED);
++ else
++ /* Make sure HBA is alive */
++ lpfc_issue_hb_tmo(phba);
+
+ if (!list_empty(&abort_list))
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
+diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
+index d54fd153cb115..f59de61803dc8 100644
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -7563,6 +7563,8 @@ lpfc_disable_pci_dev(struct lpfc_hba *phba)
+ void
+ lpfc_reset_hba(struct lpfc_hba *phba)
+ {
++ int rc = 0;
++
+ /* If resets are disabled then set error state and return. */
+ if (!phba->cfg_enable_hba_reset) {
+ phba->link_state = LPFC_HBA_ERROR;
+@@ -7573,13 +7575,25 @@ lpfc_reset_hba(struct lpfc_hba *phba)
+ if (phba->sli.sli_flag & LPFC_SLI_ACTIVE) {
+ lpfc_offline_prep(phba, LPFC_MBX_WAIT);
+ } else {
++ if (test_bit(MBX_TMO_ERR, &phba->bit_flags)) {
++ /* Perform a PCI function reset to start from clean */
++ rc = lpfc_pci_function_reset(phba);
++ lpfc_els_flush_all_cmd(phba);
++ }
+ lpfc_offline_prep(phba, LPFC_MBX_NO_WAIT);
+ lpfc_sli_flush_io_rings(phba);
+ }
+ lpfc_offline(phba);
+- lpfc_sli_brdrestart(phba);
+- lpfc_online(phba);
+- lpfc_unblock_mgmt_io(phba);
++ clear_bit(MBX_TMO_ERR, &phba->bit_flags);
++ if (unlikely(rc)) {
++ lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
++ "8888 PCI function reset failed rc %x\n",
++ rc);
++ } else {
++ lpfc_sli_brdrestart(phba);
++ lpfc_online(phba);
++ lpfc_unblock_mgmt_io(phba);
++ }
+ }
+
+ /**
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index b44bb3ae22ad9..427a6ac803e50 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -3919,6 +3919,8 @@ void lpfc_poll_eratt(struct timer_list *t)
+ uint64_t sli_intr, cnt;
+
+ phba = from_timer(phba, t, eratt_poll);
++ if (!(phba->hba_flag & HBA_SETUP))
++ return;
+
+ /* Here we will also keep track of interrupts per sec of the hba */
+ sli_intr = phba->sli.slistat.sli_intr;
+@@ -7712,7 +7714,9 @@ lpfc_sli4_repost_sgl_list(struct lpfc_hba *phba,
+ spin_unlock_irq(&phba->hbalock);
+ } else {
+ lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+- "3161 Failure to post sgl to port.\n");
++ "3161 Failure to post sgl to port,status %x "
++ "blkcnt %d totalcnt %d postcnt %d\n",
++ status, block_cnt, total_cnt, post_cnt);
+ return -EIO;
+ }
+
+@@ -8495,6 +8499,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
+ spin_unlock_irq(&phba->hbalock);
+ }
+ }
++ phba->hba_flag &= ~HBA_SETUP;
+
+ lpfc_sli4_dip(phba);
+
+@@ -9317,6 +9322,7 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
+ * would get IOCB_ERROR from lpfc_sli_issue_iocb, allowing
+ * it to fail all outstanding SCSI IO.
+ */
++ set_bit(MBX_TMO_ERR, &phba->bit_flags);
+ spin_lock_irq(&phba->pport->work_port_lock);
+ phba->pport->work_port_events &= ~WORKER_MBOX_TMO;
+ spin_unlock_irq(&phba->pport->work_port_lock);
+--
+2.40.1
+
--- /dev/null
+From 4373f972ab021fcd7d43988a810a2717c8fcd288 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Sep 2023 11:08:09 +0800
+Subject: scsi: lpfc: Fix the NULL vs IS_ERR() bug for debugfs_create_file()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 7dcc683db3639eadd11bf0d59a09088a43de5e22 ]
+
+Since debugfs_create_file() returns ERR_PTR and never NULL, use IS_ERR() to
+check the return value.
+
+Fixes: 2fcbc569b9f5 ("scsi: lpfc: Make debugfs ktime stats generic for NVME and SCSI")
+Fixes: 4c47efc140fa ("scsi: lpfc: Move SCSI and NVME Stats to hardware queue structures")
+Fixes: 6a828b0f6192 ("scsi: lpfc: Support non-uniform allocation of MSIX vectors to hardware queues")
+Fixes: 95bfc6d8ad86 ("scsi: lpfc: Make FW logging dynamically configurable")
+Fixes: 9f77870870d8 ("scsi: lpfc: Add debugfs support for cm framework buffers")
+Fixes: c490850a0947 ("scsi: lpfc: Adapt partitioned XRI lists to efficient sharing")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Link: https://lore.kernel.org/r/20230906030809.2847970-1-ruanjinjie@huawei.com
+Reviewed-by: Justin Tee <justin.tee@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/lpfc/lpfc_debugfs.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
+index 3e365e5e194a2..250d423710ca4 100644
+--- a/drivers/scsi/lpfc/lpfc_debugfs.c
++++ b/drivers/scsi/lpfc/lpfc_debugfs.c
+@@ -6069,7 +6069,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
+ phba->hba_debugfs_root,
+ phba,
+ &lpfc_debugfs_op_multixripools);
+- if (!phba->debug_multixri_pools) {
++ if (IS_ERR(phba->debug_multixri_pools)) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0527 Cannot create debugfs multixripools\n");
+ goto debug_failed;
+@@ -6081,7 +6081,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
+ debugfs_create_file(name, S_IFREG | 0644,
+ phba->hba_debugfs_root,
+ phba, &lpfc_cgn_buffer_op);
+- if (!phba->debug_cgn_buffer) {
++ if (IS_ERR(phba->debug_cgn_buffer)) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "6527 Cannot create debugfs "
+ "cgn_buffer\n");
+@@ -6094,7 +6094,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
+ debugfs_create_file(name, S_IFREG | 0644,
+ phba->hba_debugfs_root,
+ phba, &lpfc_rx_monitor_op);
+- if (!phba->debug_rx_monitor) {
++ if (IS_ERR(phba->debug_rx_monitor)) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "6528 Cannot create debugfs "
+ "rx_monitor\n");
+@@ -6107,7 +6107,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
+ debugfs_create_file(name, 0644,
+ phba->hba_debugfs_root,
+ phba, &lpfc_debugfs_ras_log);
+- if (!phba->debug_ras_log) {
++ if (IS_ERR(phba->debug_ras_log)) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "6148 Cannot create debugfs"
+ " ras_log\n");
+@@ -6128,7 +6128,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
+ debugfs_create_file(name, S_IFREG | 0644,
+ phba->hba_debugfs_root,
+ phba, &lpfc_debugfs_op_lockstat);
+- if (!phba->debug_lockstat) {
++ if (IS_ERR(phba->debug_lockstat)) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "4610 Can't create debugfs lockstat\n");
+ goto debug_failed;
+@@ -6354,7 +6354,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
+ debugfs_create_file(name, 0644,
+ vport->vport_debugfs_root,
+ vport, &lpfc_debugfs_op_scsistat);
+- if (!vport->debug_scsistat) {
++ if (IS_ERR(vport->debug_scsistat)) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "4611 Cannot create debugfs scsistat\n");
+ goto debug_failed;
+@@ -6365,7 +6365,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
+ debugfs_create_file(name, 0644,
+ vport->vport_debugfs_root,
+ vport, &lpfc_debugfs_op_ioktime);
+- if (!vport->debug_ioktime) {
++ if (IS_ERR(vport->debug_ioktime)) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0815 Cannot create debugfs ioktime\n");
+ goto debug_failed;
+--
+2.40.1
+
--- /dev/null
+From 6471e3ad81b07aadefff675bd8973f90d1ab472f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 31 Aug 2023 22:09:29 +0800
+Subject: scsi: qla2xxx: Fix NULL vs IS_ERR() bug for debugfs_create_dir()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit d0b0822e32dbae80bbcb3cc86f34d28539d913df ]
+
+Since both debugfs_create_dir() and debugfs_create_file() return ERR_PTR
+and never NULL, use IS_ERR() instead of checking for NULL.
+
+Fixes: 1e98fb0f9208 ("scsi: qla2xxx: Setup debugfs entries for remote ports")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Link: https://lore.kernel.org/r/20230831140930.3166359-1-ruanjinjie@huawei.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_dfs.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
+index f060e593685de..a7a364760b800 100644
+--- a/drivers/scsi/qla2xxx/qla_dfs.c
++++ b/drivers/scsi/qla2xxx/qla_dfs.c
+@@ -116,7 +116,7 @@ qla2x00_dfs_create_rport(scsi_qla_host_t *vha, struct fc_port *fp)
+
+ sprintf(wwn, "pn-%016llx", wwn_to_u64(fp->port_name));
+ fp->dfs_rport_dir = debugfs_create_dir(wwn, vha->dfs_rport_root);
+- if (!fp->dfs_rport_dir)
++ if (IS_ERR(fp->dfs_rport_dir))
+ return;
+ if (NVME_TARGET(vha->hw, fp))
+ debugfs_create_file("dev_loss_tmo", 0600, fp->dfs_rport_dir,
+@@ -708,14 +708,14 @@ qla2x00_dfs_setup(scsi_qla_host_t *vha)
+ if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha)) {
+ ha->tgt.dfs_naqp = debugfs_create_file("naqp",
+ 0400, ha->dfs_dir, vha, &dfs_naqp_ops);
+- if (!ha->tgt.dfs_naqp) {
++ if (IS_ERR(ha->tgt.dfs_naqp)) {
+ ql_log(ql_log_warn, vha, 0xd011,
+ "Unable to create debugFS naqp node.\n");
+ goto out;
+ }
+ }
+ vha->dfs_rport_root = debugfs_create_dir("rports", ha->dfs_dir);
+- if (!vha->dfs_rport_root) {
++ if (IS_ERR(vha->dfs_rport_root)) {
+ ql_log(ql_log_warn, vha, 0xd012,
+ "Unable to create debugFS rports node.\n");
+ goto out;
+--
+2.40.1
+
--- /dev/null
+From c0080ca18194b18690edbffa64aae6ad7a83a0c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 31 Aug 2023 20:34:59 +0200
+Subject: scsi: target: core: Fix target_cmd_counter leak
+
+From: David Disseldorp <ddiss@suse.de>
+
+[ Upstream commit d14e3e553e05cb763964c991fe6acb0a6a1c6f9c ]
+
+The target_cmd_counter struct allocated via target_alloc_cmd_counter() is
+never freed, resulting in leaks across various transport types, e.g.:
+
+ unreferenced object 0xffff88801f920120 (size 96):
+ comm "sh", pid 102, jiffies 4294892535 (age 713.412s)
+ hex dump (first 32 bytes):
+ 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00 00 00 00 00 00 00 00 38 01 92 1f 80 88 ff ff ........8.......
+ backtrace:
+ [<00000000e58a6252>] kmalloc_trace+0x11/0x20
+ [<0000000043af4b2f>] target_alloc_cmd_counter+0x17/0x90 [target_core_mod]
+ [<000000007da2dfa7>] target_setup_session+0x2d/0x140 [target_core_mod]
+ [<0000000068feef86>] tcm_loop_tpg_nexus_store+0x19b/0x350 [tcm_loop]
+ [<000000006a80e021>] configfs_write_iter+0xb1/0x120
+ [<00000000e9f4d860>] vfs_write+0x2e4/0x3c0
+ [<000000008143433b>] ksys_write+0x80/0xb0
+ [<00000000a7df29b2>] do_syscall_64+0x42/0x90
+ [<0000000053f45fb8>] entry_SYSCALL_64_after_hwframe+0x6e/0xd8
+
+Free the structure alongside the corresponding iscsit_conn / se_sess
+parent.
+
+Signed-off-by: David Disseldorp <ddiss@suse.de>
+Link: https://lore.kernel.org/r/20230831183459.6938-1-ddiss@suse.de
+Fixes: becd9be6069e ("scsi: target: Move sess cmd counter to new struct")
+Reviewed-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/target/target_core_transport.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
+index 687adc9e086ca..0686882bcbda3 100644
+--- a/drivers/target/target_core_transport.c
++++ b/drivers/target/target_core_transport.c
+@@ -264,6 +264,7 @@ void target_free_cmd_counter(struct target_cmd_counter *cmd_cnt)
+ percpu_ref_put(&cmd_cnt->refcnt);
+
+ percpu_ref_exit(&cmd_cnt->refcnt);
++ kfree(cmd_cnt);
+ }
+ EXPORT_SYMBOL_GPL(target_free_cmd_counter);
+
+--
+2.40.1
+
--- /dev/null
+From 99127138e2d70bb6a4e8d61ac015ce1f6da082fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Jul 2023 18:26:37 +0300
+Subject: scsi: target: iscsi: Fix buffer overflow in
+ lio_target_nacl_info_show()
+
+From: Konstantin Shelekhin <k.shelekhin@yadro.com>
+
+[ Upstream commit 801f287c93ff95582b0a2d2163f12870a2f076d4 ]
+
+The function lio_target_nacl_info_show() uses sprintf() in a loop to print
+details for every iSCSI connection in a session without checking for the
+buffer length. With enough iSCSI connections it's possible to overflow the
+buffer provided by configfs and corrupt the memory.
+
+This patch replaces sprintf() with sysfs_emit_at() that checks for buffer
+boundries.
+
+Signed-off-by: Konstantin Shelekhin <k.shelekhin@yadro.com>
+Link: https://lore.kernel.org/r/20230722152657.168859-2-k.shelekhin@yadro.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/target/iscsi/iscsi_target_configfs.c | 54 ++++++++++----------
+ 1 file changed, 27 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
+index 5d0f51822414e..c142a67dc7cc2 100644
+--- a/drivers/target/iscsi/iscsi_target_configfs.c
++++ b/drivers/target/iscsi/iscsi_target_configfs.c
+@@ -533,102 +533,102 @@ static ssize_t lio_target_nacl_info_show(struct config_item *item, char *page)
+ spin_lock_bh(&se_nacl->nacl_sess_lock);
+ se_sess = se_nacl->nacl_sess;
+ if (!se_sess) {
+- rb += sprintf(page+rb, "No active iSCSI Session for Initiator"
++ rb += sysfs_emit_at(page, rb, "No active iSCSI Session for Initiator"
+ " Endpoint: %s\n", se_nacl->initiatorname);
+ } else {
+ sess = se_sess->fabric_sess_ptr;
+
+- rb += sprintf(page+rb, "InitiatorName: %s\n",
++ rb += sysfs_emit_at(page, rb, "InitiatorName: %s\n",
+ sess->sess_ops->InitiatorName);
+- rb += sprintf(page+rb, "InitiatorAlias: %s\n",
++ rb += sysfs_emit_at(page, rb, "InitiatorAlias: %s\n",
+ sess->sess_ops->InitiatorAlias);
+
+- rb += sprintf(page+rb,
++ rb += sysfs_emit_at(page, rb,
+ "LIO Session ID: %u ISID: 0x%6ph TSIH: %hu ",
+ sess->sid, sess->isid, sess->tsih);
+- rb += sprintf(page+rb, "SessionType: %s\n",
++ rb += sysfs_emit_at(page, rb, "SessionType: %s\n",
+ (sess->sess_ops->SessionType) ?
+ "Discovery" : "Normal");
+- rb += sprintf(page+rb, "Session State: ");
++ rb += sysfs_emit_at(page, rb, "Session State: ");
+ switch (sess->session_state) {
+ case TARG_SESS_STATE_FREE:
+- rb += sprintf(page+rb, "TARG_SESS_FREE\n");
++ rb += sysfs_emit_at(page, rb, "TARG_SESS_FREE\n");
+ break;
+ case TARG_SESS_STATE_ACTIVE:
+- rb += sprintf(page+rb, "TARG_SESS_STATE_ACTIVE\n");
++ rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_ACTIVE\n");
+ break;
+ case TARG_SESS_STATE_LOGGED_IN:
+- rb += sprintf(page+rb, "TARG_SESS_STATE_LOGGED_IN\n");
++ rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_LOGGED_IN\n");
+ break;
+ case TARG_SESS_STATE_FAILED:
+- rb += sprintf(page+rb, "TARG_SESS_STATE_FAILED\n");
++ rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_FAILED\n");
+ break;
+ case TARG_SESS_STATE_IN_CONTINUE:
+- rb += sprintf(page+rb, "TARG_SESS_STATE_IN_CONTINUE\n");
++ rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_IN_CONTINUE\n");
+ break;
+ default:
+- rb += sprintf(page+rb, "ERROR: Unknown Session"
++ rb += sysfs_emit_at(page, rb, "ERROR: Unknown Session"
+ " State!\n");
+ break;
+ }
+
+- rb += sprintf(page+rb, "---------------------[iSCSI Session"
++ rb += sysfs_emit_at(page, rb, "---------------------[iSCSI Session"
+ " Values]-----------------------\n");
+- rb += sprintf(page+rb, " CmdSN/WR : CmdSN/WC : ExpCmdSN"
++ rb += sysfs_emit_at(page, rb, " CmdSN/WR : CmdSN/WC : ExpCmdSN"
+ " : MaxCmdSN : ITT : TTT\n");
+ max_cmd_sn = (u32) atomic_read(&sess->max_cmd_sn);
+- rb += sprintf(page+rb, " 0x%08x 0x%08x 0x%08x 0x%08x"
++ rb += sysfs_emit_at(page, rb, " 0x%08x 0x%08x 0x%08x 0x%08x"
+ " 0x%08x 0x%08x\n",
+ sess->cmdsn_window,
+ (max_cmd_sn - sess->exp_cmd_sn) + 1,
+ sess->exp_cmd_sn, max_cmd_sn,
+ sess->init_task_tag, sess->targ_xfer_tag);
+- rb += sprintf(page+rb, "----------------------[iSCSI"
++ rb += sysfs_emit_at(page, rb, "----------------------[iSCSI"
+ " Connections]-------------------------\n");
+
+ spin_lock(&sess->conn_lock);
+ list_for_each_entry(conn, &sess->sess_conn_list, conn_list) {
+- rb += sprintf(page+rb, "CID: %hu Connection"
++ rb += sysfs_emit_at(page, rb, "CID: %hu Connection"
+ " State: ", conn->cid);
+ switch (conn->conn_state) {
+ case TARG_CONN_STATE_FREE:
+- rb += sprintf(page+rb,
++ rb += sysfs_emit_at(page, rb,
+ "TARG_CONN_STATE_FREE\n");
+ break;
+ case TARG_CONN_STATE_XPT_UP:
+- rb += sprintf(page+rb,
++ rb += sysfs_emit_at(page, rb,
+ "TARG_CONN_STATE_XPT_UP\n");
+ break;
+ case TARG_CONN_STATE_IN_LOGIN:
+- rb += sprintf(page+rb,
++ rb += sysfs_emit_at(page, rb,
+ "TARG_CONN_STATE_IN_LOGIN\n");
+ break;
+ case TARG_CONN_STATE_LOGGED_IN:
+- rb += sprintf(page+rb,
++ rb += sysfs_emit_at(page, rb,
+ "TARG_CONN_STATE_LOGGED_IN\n");
+ break;
+ case TARG_CONN_STATE_IN_LOGOUT:
+- rb += sprintf(page+rb,
++ rb += sysfs_emit_at(page, rb,
+ "TARG_CONN_STATE_IN_LOGOUT\n");
+ break;
+ case TARG_CONN_STATE_LOGOUT_REQUESTED:
+- rb += sprintf(page+rb,
++ rb += sysfs_emit_at(page, rb,
+ "TARG_CONN_STATE_LOGOUT_REQUESTED\n");
+ break;
+ case TARG_CONN_STATE_CLEANUP_WAIT:
+- rb += sprintf(page+rb,
++ rb += sysfs_emit_at(page, rb,
+ "TARG_CONN_STATE_CLEANUP_WAIT\n");
+ break;
+ default:
+- rb += sprintf(page+rb,
++ rb += sysfs_emit_at(page, rb,
+ "ERROR: Unknown Connection State!\n");
+ break;
+ }
+
+- rb += sprintf(page+rb, " Address %pISc %s", &conn->login_sockaddr,
++ rb += sysfs_emit_at(page, rb, " Address %pISc %s", &conn->login_sockaddr,
+ (conn->network_transport == ISCSI_TCP) ?
+ "TCP" : "SCTP");
+- rb += sprintf(page+rb, " StatSN: 0x%08x\n",
++ rb += sysfs_emit_at(page, rb, " StatSN: 0x%08x\n",
+ conn->stat_sn);
+ }
+ spin_unlock(&sess->conn_lock);
+--
+2.40.1
+
--- /dev/null
+From 74a991b46959eac113cb958ef656dbc50d3e38c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Jul 2023 02:32:05 +0800
+Subject: selftests/nolibc: fix up kernel parameters support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zhangjin Wu <falcon@tinylab.org>
+
+[ Upstream commit c388c9920da2679f62bec48d00ca9e80e9d0a364 ]
+
+kernel parameters allow pass two types of strings, one type is like
+'noapic', another type is like 'panic=5', the first type is passed as
+arguments of the init program, the second type is passed as environment
+variables of the init program.
+
+when users pass kernel parameters like this:
+
+ noapic NOLIBC_TEST=syscall
+
+our nolibc-test program will use the test setting from argv[1] and
+ignore the one from NOLIBC_TEST environment variable, and at last, it
+will print the following line and ignore the whole test setting.
+
+ Ignoring unknown test name 'noapic'
+
+reversing the parsing order does solve the above issue:
+
+ test = getenv("NOLIBC_TEST");
+ if (test)
+ test = argv[1];
+
+but it still doesn't work with such kernel parameters (without
+NOLIBC_TEST environment variable):
+
+ noapic FOO=bar
+
+To support all of the potential kernel parameters, let's verify the test
+setting from both of argv[1] and NOLIBC_TEST environment variable.
+
+Reviewed-by: Thomas Weißschuh <linux@weissschuh.net>
+Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
+Signed-off-by: Willy Tarreau <w@1wt.eu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/nolibc/nolibc-test.c | 33 ++++++++++++++++++--
+ 1 file changed, 31 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
+index 78bced95ac630..f8e8e8d2a5e18 100644
+--- a/tools/testing/selftests/nolibc/nolibc-test.c
++++ b/tools/testing/selftests/nolibc/nolibc-test.c
+@@ -630,6 +630,35 @@ static struct test test_names[] = {
+ { 0 }
+ };
+
++int is_setting_valid(char *test)
++{
++ int idx, len, test_len, valid = 0;
++ char delimiter;
++
++ if (!test)
++ return valid;
++
++ test_len = strlen(test);
++
++ for (idx = 0; test_names[idx].name; idx++) {
++ len = strlen(test_names[idx].name);
++ if (test_len < len)
++ continue;
++
++ if (strncmp(test, test_names[idx].name, len) != 0)
++ continue;
++
++ delimiter = test[len];
++ if (delimiter != ':' && delimiter != ',' && delimiter != '\0')
++ continue;
++
++ valid = 1;
++ break;
++ }
++
++ return valid;
++}
++
+ int main(int argc, char **argv, char **envp)
+ {
+ int min = 0;
+@@ -655,10 +684,10 @@ int main(int argc, char **argv, char **envp)
+ * syscall:5-15[:.*],stdlib:8-10
+ */
+ test = argv[1];
+- if (!test)
++ if (!is_setting_valid(test))
+ test = getenv("NOLIBC_TEST");
+
+- if (test) {
++ if (is_setting_valid(test)) {
+ char *comma, *colon, *dash, *value;
+
+ do {
+--
+2.40.1
+
--- /dev/null
+From 4d3b62422b5f0a6fae79131bf4e35c5858bc6366 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Sep 2023 10:10:39 +0900
+Subject: selftests: tracing: Fix to unmount tracefs for recovering environment
+
+From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+
+[ Upstream commit 7e021da80f48582171029714f8a487347f29dddb ]
+
+Fix to unmount the tracefs if the ftracetest mounted it for recovering
+system environment. If the tracefs is already mounted, this does nothing.
+
+Suggested-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/all/29fce076-746c-4650-8358-b4e0fa215cf7@sirena.org.uk/
+Fixes: cbd965bde74c ("ftrace/selftests: Return the skip code when tracing directory not configured in kernel")
+Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Reviewed-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ftrace/ftracetest | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/tools/testing/selftests/ftrace/ftracetest b/tools/testing/selftests/ftrace/ftracetest
+index c3311c8c40890..ef0edb7a71e37 100755
+--- a/tools/testing/selftests/ftrace/ftracetest
++++ b/tools/testing/selftests/ftrace/ftracetest
+@@ -30,6 +30,9 @@ err_ret=1
+ # kselftest skip code is 4
+ err_skip=4
+
++# umount required
++UMOUNT_DIR=""
++
+ # cgroup RT scheduling prevents chrt commands from succeeding, which
+ # induces failures in test wakeup tests. Disable for the duration of
+ # the tests.
+@@ -44,6 +47,9 @@ setup() {
+
+ cleanup() {
+ echo $sched_rt_runtime_orig > $sched_rt_runtime
++ if [ -n "${UMOUNT_DIR}" ]; then
++ umount ${UMOUNT_DIR} ||:
++ fi
+ }
+
+ errexit() { # message
+@@ -155,11 +161,13 @@ if [ -z "$TRACING_DIR" ]; then
+ mount -t tracefs nodev /sys/kernel/tracing ||
+ errexit "Failed to mount /sys/kernel/tracing"
+ TRACING_DIR="/sys/kernel/tracing"
++ UMOUNT_DIR=${TRACING_DIR}
+ # If debugfs exists, then so does /sys/kernel/debug
+ elif [ -d "/sys/kernel/debug" ]; then
+ mount -t debugfs nodev /sys/kernel/debug ||
+ errexit "Failed to mount /sys/kernel/debug"
+ TRACING_DIR="/sys/kernel/debug/tracing"
++ UMOUNT_DIR=${TRACING_DIR}
+ else
+ err_ret=$err_skip
+ errexit "debugfs and tracefs are not configured in this kernel"
+--
+2.40.1
+
--- /dev/null
+From 3939c046f21125cb1ad4ca3cf6aac12f14c5d545 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Aug 2023 15:56:42 +0200
+Subject: serial: cpm_uart: Avoid suspicious locking
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 36ef11d311f405e55ad8e848c19b212ff71ef536 ]
+
+ CHECK drivers/tty/serial/cpm_uart/cpm_uart_core.c
+drivers/tty/serial/cpm_uart/cpm_uart_core.c:1271:39: warning: context imbalance in 'cpm_uart_console_write' - unexpected unlock
+
+Allthough 'nolock' is not expected to change, sparse find the following
+form suspicious:
+
+ if (unlikely(nolock)) {
+ local_irq_save(flags);
+ } else {
+ spin_lock_irqsave(&pinfo->port.lock, flags);
+ }
+
+ cpm_uart_early_write(pinfo, s, count, true);
+
+ if (unlikely(nolock)) {
+ local_irq_restore(flags);
+ } else {
+ spin_unlock_irqrestore(&pinfo->port.lock, flags);
+ }
+
+Rewrite it a more obvious form:
+
+ if (unlikely(oops_in_progress)) {
+ local_irq_save(flags);
+ cpm_uart_early_write(pinfo, s, count, true);
+ local_irq_restore(flags);
+ } else {
+ spin_lock_irqsave(&pinfo->port.lock, flags);
+ cpm_uart_early_write(pinfo, s, count, true);
+ spin_unlock_irqrestore(&pinfo->port.lock, flags);
+ }
+
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Link: https://lore.kernel.org/r/f7da5cdc9287960185829cfef681a7d8614efa1f.1691068700.git.christophe.leroy@csgroup.eu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/cpm_uart/cpm_uart_core.c | 13 ++++---------
+ 1 file changed, 4 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
+index b4369ed45ae2d..bb25691f50007 100644
+--- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c
++++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
+@@ -1257,19 +1257,14 @@ static void cpm_uart_console_write(struct console *co, const char *s,
+ {
+ struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index];
+ unsigned long flags;
+- int nolock = oops_in_progress;
+
+- if (unlikely(nolock)) {
++ if (unlikely(oops_in_progress)) {
+ local_irq_save(flags);
+- } else {
+- spin_lock_irqsave(&pinfo->port.lock, flags);
+- }
+-
+- cpm_uart_early_write(pinfo, s, count, true);
+-
+- if (unlikely(nolock)) {
++ cpm_uart_early_write(pinfo, s, count, true);
+ local_irq_restore(flags);
+ } else {
++ spin_lock_irqsave(&pinfo->port.lock, flags);
++ cpm_uart_early_write(pinfo, s, count, true);
+ spin_unlock_irqrestore(&pinfo->port.lock, flags);
+ }
+ }
+--
+2.40.1
+
--- /dev/null
+autofs-fix-memory-leak-of-waitqueues-in-autofs_catat.patch
+btrfs-output-extra-debug-info-if-we-failed-to-find-a.patch
+locks-fix-kasan-use-after-free-in-trace_event_raw_ev.patch
+acpica-add-aml_no_operand_resolve-flag-to-timer.patch
+kernel-fork-beware-of-__put_task_struct-calling-cont.patch
+rcuscale-move-rcu_scale_writer-schedule_timeout_unin.patch
+scftorture-forgive-memory-allocation-failure-if-kasa.patch
+acpi-video-add-backlight-native-dmi-quirk-for-lenovo.patch
+perf-smmuv3-enable-hisilicon-erratum-162001900-quirk.patch
+perf-imx_ddr-speed-up-overflow-frequency-of-cycle.patch
+hw_breakpoint-fix-single-stepping-when-using-bpf_ove.patch
+acpi-x86-s2idle-catch-multiple-acpi_type_package-obj.patch
+selftests-nolibc-fix-up-kernel-parameters-support.patch
+devlink-remove-reload-failed-checks-in-params-get-se.patch
+crypto-lrw-xts-replace-strlcpy-with-strscpy.patch
+ice-don-t-tx-before-switchdev-is-fully-configured.patch
+wifi-ath9k-fix-fortify-warnings.patch
+wifi-ath9k-fix-printk-specifier.patch
+wifi-mwifiex-fix-fortify-warning.patch
+mt76-mt7921-don-t-assume-adequate-headroom-for-sdio-.patch
+wifi-wil6210-fix-fortify-warnings.patch
+can-sun4i_can-add-acceptance-register-quirk.patch
+can-sun4i_can-add-support-for-the-allwinner-d1.patch
+net-use-sockaddr_storage-for-getsockopt-so_peername.patch
+net-ipv4-return-the-real-errno-instead-of-einval.patch
+crypto-lib-mpi-avoid-null-pointer-deref-in-mpi_cmp_u.patch
+bluetooth-fix-hci_suspend_sync-crash.patch
+netlink-convert-nlk-flags-to-atomic-flags.patch
+tpm_tis-resend-command-to-recover-from-data-transfer.patch
+mmc-sdhci-esdhc-imx-improve-esdhc_flag_err010450.patch
+alx-fix-oob-read-compiler-warning.patch
+wifi-mac80211-check-s1g-action-frame-size.patch
+netfilter-ebtables-fix-fortify-warnings-in-size_entr.patch
+wifi-cfg80211-reject-auth-assoc-to-ap-with-our-addre.patch
+wifi-cfg80211-ocb-don-t-leave-if-not-joined.patch
+wifi-mac80211-check-for-station-first-in-client-prob.patch
+wifi-mac80211_hwsim-drop-short-frames.patch
+libbpf-free-btf_vmlinux-when-closing-bpf_object.patch
+drm-bridge-tc358762-instruct-dsi-host-to-generate-hs.patch
+drm-edid-add-quirk-for-osvr-hdk-2.0.patch
+arm64-dts-qcom-sm6125-pdx201-correct-ramoops-pmsg-si.patch
+arm64-dts-qcom-sm6350-correct-ramoops-pmsg-size.patch
+arm64-dts-qcom-sm8150-kumano-correct-ramoops-pmsg-si.patch
+arm64-dts-qcom-sm8250-edo-correct-ramoops-pmsg-size.patch
+samples-hw_breakpoint-fix-kernel-bug-invalid-opcode-.patch
+drm-amd-display-fix-underflow-issue-on-175hz-timing.patch
+asoc-sof-topology-simplify-code-to-prevent-static-an.patch
+asoc-intel-sof_sdw-update-bt-offload-config-for-soun.patch
+alsa-hda-intel-dsp-cfg-add-lunarlake-support.patch
+drm-amd-display-use-dtbclk-as-refclk-instead-of-dpre.patch
+drm-amd-display-blocking-invalid-420-modes-on-hdmi-t.patch
+drm-amd-display-blocking-invalid-420-modes-on-hdmi-t.patch-22374
+drm-exynos-fix-a-possible-null-pointer-dereference-d.patch
+drm-mediatek-dp-change-logging-to-dev-for-mtk_dp_aux.patch
+bus-ti-sysc-configure-uart-quirks-for-k3-soc.patch
+md-raid1-fix-potential-oob-in-raid1_remove_disk.patch
+ext2-fix-datatype-of-block-number-in-ext2_xattr_set2.patch
+fs-jfs-prevent-double-free-in-dbunmount-after-failed.patch
+jfs-fix-invalid-free-of-jfs_ip-ipimap-i_imap-in-diun.patch
+pci-dwc-provide-deinit-callback-for-i.mx.patch
+arm-9317-1-kexec-make-smp-stop-calls-asynchronous.patch
+powerpc-pseries-fix-possible-memory-leak-in-ibmebus_.patch
+pci-vmd-disable-bridge-window-for-domain-reset.patch
+pci-fu740-set-the-number-of-msi-vectors.patch
+media-mdp3-fix-resource-leaks-in-of_find_device_by_n.patch
+media-dvb-usb-v2-af9035-fix-null-ptr-deref-in-af9035.patch
+media-dw2102-fix-null-ptr-deref-in-dw2102_i2c_transf.patch
+media-af9005-fix-null-ptr-deref-in-af9005_i2c_xfer.patch
+media-anysee-fix-null-ptr-deref-in-anysee_master_xfe.patch
+media-az6007-fix-null-ptr-deref-in-az6007_i2c_xfer.patch
+media-dvb-usb-v2-gl861-fix-null-ptr-deref-in-gl861_i.patch
+scsi-lpfc-abort-outstanding-els-cmds-when-mailbox-ti.patch
+media-tuners-qt1010-replace-bug_on-with-a-regular-er.patch
+media-pci-cx23885-replace-bug-with-error-return.patch
+usb-cdns3-put-the-cdns-set-active-part-outside-the-s.patch
+usb-gadget-fsl_qe_udc-validate-endpoint-index-for-ch.patch
+tools-iio-iio_generic_buffer-fix-some-integer-type-a.patch
+scsi-target-iscsi-fix-buffer-overflow-in-lio_target_.patch
+serial-cpm_uart-avoid-suspicious-locking.patch
+misc-open-dice-make-open_dice-depend-on-has_iomem.patch
+usb-ehci-add-workaround-for-chipidea-portsc.pec-bug.patch
+usb-chipidea-add-workaround-for-chipidea-pec-bug.patch
+media-pci-ipu3-cio2-initialise-timing-struct-to-avoi.patch
+kobject-add-sanity-check-for-kset-kobj.ktype-in-kset.patch
+interconnect-fix-locking-for-runpm-vs-reclaim.patch
+printk-keep-non-panic-cpus-out-of-console-lock.patch
+printk-consolidate-console-deferred-printing.patch
+netfilter-nf_tables-make-validation-state-per-table.patch
+netfilter-nf_tables-gc-transaction-api-to-avoid-race.patch
+netfilter-nf_tables-adapt-set-backend-to-use-gc-tran.patch
+netfilter-nft_set_hash-mark-set-element-as-dead-when.patch
+netfilter-nf_tables-remove-busy-mark-and-gc-batch-ap.patch
+netfilter-nf_tables-fix-kdoc-warnings-after-gc-rewor.patch
+netfilter-nf_tables-fix-gc-transaction-races-with-ne.patch
+netfilter-nf_tables-gc-transaction-race-with-netns-d.patch
+dma-buf-add-unlocked-variant-of-attachment-mapping-f.patch
+misc-fastrpc-prepare-to-dynamic-dma-buf-locking-spec.patch
+misc-fastrpc-fix-incorrect-dma-mapping-unmap-request.patch
+mips-use-grep-e-instead-of-egrep.patch
+btrfs-add-a-helper-to-read-the-superblock-metadata_u.patch
+btrfs-compare-the-correct-fsid-metadata_uuid-in-btrf.patch
+block-factor-out-a-bvec_set_page-helper.patch
+nvmet-use-bvec_set_page-to-initialize-bvecs.patch
+nvmet-tcp-pass-iov_len-instead-of-sg-length-to-bvec_.patch
+drm-gm12u320-fix-the-timeout-usage-for-usb_bulk_msg.patch
+scsi-qla2xxx-fix-null-vs-is_err-bug-for-debugfs_crea.patch
+selftests-tracing-fix-to-unmount-tracefs-for-recover.patch
+x86-ibt-suppress-spurious-endbr.patch
+riscv-kexec-align-the-kexeced-kernel-entry.patch
+scsi-target-core-fix-target_cmd_counter-leak.patch
+scsi-lpfc-fix-the-null-vs-is_err-bug-for-debugfs_cre.patch
+panic-reenable-preemption-in-warn-slowpath.patch
+x86-boot-compressed-reserve-more-memory-for-page-tab.patch
+x86-purgatory-remove-lto-flags.patch
+samples-hw_breakpoint-fix-building-without-module-un.patch
+md-raid1-fix-error-iso-c90-forbids-mixed-declaration.patch
--- /dev/null
+From 40800c934c2fd4ec9062edd51dbc3b69cfb0c0c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 09:24:07 +0000
+Subject: tools: iio: iio_generic_buffer: Fix some integer type and calculation
+
+From: Chenyuan Mi <michenyuan@huawei.com>
+
+[ Upstream commit 49d736313d0975ddeb156f4f59801da833f78b30 ]
+
+In function size_from_channelarray(), the return value 'bytes' is defined
+as int type. However, the calcution of 'bytes' in this function is designed
+to use the unsigned int type. So it is necessary to change 'bytes' type to
+unsigned int to avoid integer overflow.
+
+The size_from_channelarray() is called in main() function, its return value
+is directly multipled by 'buf_len' and then used as the malloc() parameter.
+The 'buf_len' is completely controllable by user, thus a multiplication
+overflow may occur here. This could allocate an unexpected small area.
+
+Signed-off-by: Chenyuan Mi <michenyuan@huawei.com>
+Link: https://lore.kernel.org/r/20230725092407.62545-1-michenyuan@huawei.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/iio/iio_generic_buffer.c | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/tools/iio/iio_generic_buffer.c b/tools/iio/iio_generic_buffer.c
+index f8deae4e26a15..44bbf80f0cfdd 100644
+--- a/tools/iio/iio_generic_buffer.c
++++ b/tools/iio/iio_generic_buffer.c
+@@ -51,9 +51,9 @@ enum autochan {
+ * Has the side effect of filling the channels[i].location values used
+ * in processing the buffer output.
+ **/
+-static int size_from_channelarray(struct iio_channel_info *channels, int num_channels)
++static unsigned int size_from_channelarray(struct iio_channel_info *channels, int num_channels)
+ {
+- int bytes = 0;
++ unsigned int bytes = 0;
+ int i = 0;
+
+ while (i < num_channels) {
+@@ -348,7 +348,7 @@ int main(int argc, char **argv)
+ ssize_t read_size;
+ int dev_num = -1, trig_num = -1;
+ char *buffer_access = NULL;
+- int scan_size;
++ unsigned int scan_size;
+ int noevents = 0;
+ int notrigger = 0;
+ char *dummy;
+@@ -674,7 +674,16 @@ int main(int argc, char **argv)
+ }
+
+ scan_size = size_from_channelarray(channels, num_channels);
+- data = malloc(scan_size * buf_len);
++
++ size_t total_buf_len = scan_size * buf_len;
++
++ if (scan_size > 0 && total_buf_len / scan_size != buf_len) {
++ ret = -EFAULT;
++ perror("Integer overflow happened when calculate scan_size * buf_len");
++ goto error;
++ }
++
++ data = malloc(total_buf_len);
+ if (!data) {
+ ret = -ENOMEM;
+ goto error;
+--
+2.40.1
+
--- /dev/null
+From bd6732c39f72fe7df1cccafe11aa0901b81e033c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jun 2023 20:02:59 +0200
+Subject: tpm_tis: Resend command to recover from data transfer errors
+
+From: Alexander Steffen <Alexander.Steffen@infineon.com>
+
+[ Upstream commit 280db21e153d8810ce3b93640c63ae922bcb9e8e ]
+
+Similar to the transmission of TPM responses, also the transmission of TPM
+commands may become corrupted. Instead of aborting when detecting such
+issues, try resending the command again.
+
+Signed-off-by: Alexander Steffen <Alexander.Steffen@infineon.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/tpm/tpm_tis_core.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
+index 44f71f2c8cfa0..5889d9edaf940 100644
+--- a/drivers/char/tpm/tpm_tis_core.c
++++ b/drivers/char/tpm/tpm_tis_core.c
+@@ -498,10 +498,17 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
+ int rc;
+ u32 ordinal;
+ unsigned long dur;
++ unsigned int try;
+
+- rc = tpm_tis_send_data(chip, buf, len);
+- if (rc < 0)
+- return rc;
++ for (try = 0; try < TPM_RETRY; try++) {
++ rc = tpm_tis_send_data(chip, buf, len);
++ if (rc >= 0)
++ /* Data transfer done successfully */
++ break;
++ else if (rc != -EIO)
++ /* Data transfer failed, not recoverable */
++ return rc;
++ }
+
+ rc = tpm_tis_verify_crc(priv, len, buf);
+ if (rc < 0) {
+--
+2.40.1
+
--- /dev/null
+From 27b0b32496482aabf4196074e144f105e41f8952 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Jun 2023 10:19:51 +0800
+Subject: usb: cdns3: Put the cdns set active part outside the spin lock
+
+From: Xiaolei Wang <xiaolei.wang@windriver.com>
+
+[ Upstream commit 2319b9c87fe243327285f2fefd7374ffd75a65fc ]
+
+The device may be scheduled during the resume process,
+so this cannot appear in atomic operations. Since
+pm_runtime_set_active will resume suppliers, put set
+active outside the spin lock, which is only used to
+protect the struct cdns data structure, otherwise the
+kernel will report the following warning:
+
+ BUG: sleeping function called from invalid context at drivers/base/power/runtime.c:1163
+ in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 651, name: sh
+ preempt_count: 1, expected: 0
+ RCU nest depth: 0, expected: 0
+ CPU: 0 PID: 651 Comm: sh Tainted: G WC 6.1.20 #1
+ Hardware name: Freescale i.MX8QM MEK (DT)
+ Call trace:
+ dump_backtrace.part.0+0xe0/0xf0
+ show_stack+0x18/0x30
+ dump_stack_lvl+0x64/0x80
+ dump_stack+0x1c/0x38
+ __might_resched+0x1fc/0x240
+ __might_sleep+0x68/0xc0
+ __pm_runtime_resume+0x9c/0xe0
+ rpm_get_suppliers+0x68/0x1b0
+ __pm_runtime_set_status+0x298/0x560
+ cdns_resume+0xb0/0x1c0
+ cdns3_controller_resume.isra.0+0x1e0/0x250
+ cdns3_plat_resume+0x28/0x40
+
+Signed-off-by: Xiaolei Wang <xiaolei.wang@windriver.com>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Link: https://lore.kernel.org/r/20230616021952.1025854-1-xiaolei.wang@windriver.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/cdns3/cdns3-plat.c | 3 ++-
+ drivers/usb/cdns3/cdnsp-pci.c | 3 ++-
+ drivers/usb/cdns3/core.c | 15 +++++++++++----
+ drivers/usb/cdns3/core.h | 7 +++++--
+ 4 files changed, 20 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/usb/cdns3/cdns3-plat.c b/drivers/usb/cdns3/cdns3-plat.c
+index 2bc5d094548b6..726b2e4f67e4d 100644
+--- a/drivers/usb/cdns3/cdns3-plat.c
++++ b/drivers/usb/cdns3/cdns3-plat.c
+@@ -256,9 +256,10 @@ static int cdns3_controller_resume(struct device *dev, pm_message_t msg)
+ cdns3_set_platform_suspend(cdns->dev, false, false);
+
+ spin_lock_irqsave(&cdns->lock, flags);
+- cdns_resume(cdns, !PMSG_IS_AUTO(msg));
++ cdns_resume(cdns);
+ cdns->in_lpm = false;
+ spin_unlock_irqrestore(&cdns->lock, flags);
++ cdns_set_active(cdns, !PMSG_IS_AUTO(msg));
+ if (cdns->wakeup_pending) {
+ cdns->wakeup_pending = false;
+ enable_irq(cdns->wakeup_irq);
+diff --git a/drivers/usb/cdns3/cdnsp-pci.c b/drivers/usb/cdns3/cdnsp-pci.c
+index 29f433c5a6f3f..a85db23fa19f2 100644
+--- a/drivers/usb/cdns3/cdnsp-pci.c
++++ b/drivers/usb/cdns3/cdnsp-pci.c
+@@ -210,8 +210,9 @@ static int __maybe_unused cdnsp_pci_resume(struct device *dev)
+ int ret;
+
+ spin_lock_irqsave(&cdns->lock, flags);
+- ret = cdns_resume(cdns, 1);
++ ret = cdns_resume(cdns);
+ spin_unlock_irqrestore(&cdns->lock, flags);
++ cdns_set_active(cdns, 1);
+
+ return ret;
+ }
+diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c
+index dbcdf3b24b477..7b20d2d5c262e 100644
+--- a/drivers/usb/cdns3/core.c
++++ b/drivers/usb/cdns3/core.c
+@@ -522,9 +522,8 @@ int cdns_suspend(struct cdns *cdns)
+ }
+ EXPORT_SYMBOL_GPL(cdns_suspend);
+
+-int cdns_resume(struct cdns *cdns, u8 set_active)
++int cdns_resume(struct cdns *cdns)
+ {
+- struct device *dev = cdns->dev;
+ enum usb_role real_role;
+ bool role_changed = false;
+ int ret = 0;
+@@ -556,15 +555,23 @@ int cdns_resume(struct cdns *cdns, u8 set_active)
+ if (cdns->roles[cdns->role]->resume)
+ cdns->roles[cdns->role]->resume(cdns, cdns_power_is_lost(cdns));
+
++ return 0;
++}
++EXPORT_SYMBOL_GPL(cdns_resume);
++
++void cdns_set_active(struct cdns *cdns, u8 set_active)
++{
++ struct device *dev = cdns->dev;
++
+ if (set_active) {
+ pm_runtime_disable(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ }
+
+- return 0;
++ return;
+ }
+-EXPORT_SYMBOL_GPL(cdns_resume);
++EXPORT_SYMBOL_GPL(cdns_set_active);
+ #endif /* CONFIG_PM_SLEEP */
+
+ MODULE_AUTHOR("Peter Chen <peter.chen@nxp.com>");
+diff --git a/drivers/usb/cdns3/core.h b/drivers/usb/cdns3/core.h
+index 2d332a788871e..4a4dbc2c15615 100644
+--- a/drivers/usb/cdns3/core.h
++++ b/drivers/usb/cdns3/core.h
+@@ -125,10 +125,13 @@ int cdns_init(struct cdns *cdns);
+ int cdns_remove(struct cdns *cdns);
+
+ #ifdef CONFIG_PM_SLEEP
+-int cdns_resume(struct cdns *cdns, u8 set_active);
++int cdns_resume(struct cdns *cdns);
+ int cdns_suspend(struct cdns *cdns);
++void cdns_set_active(struct cdns *cdns, u8 set_active);
+ #else /* CONFIG_PM_SLEEP */
+-static inline int cdns_resume(struct cdns *cdns, u8 set_active)
++static inline int cdns_resume(struct cdns *cdns)
++{ return 0; }
++static inline int cdns_set_active(struct cdns *cdns, u8 set_active)
+ { return 0; }
+ static inline int cdns_suspend(struct cdns *cdns)
+ { return 0; }
+--
+2.40.1
+
--- /dev/null
+From 50f14f6b1667478431ac52022408c61411b22d74 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 10:44:32 +0800
+Subject: usb: chipidea: add workaround for chipidea PEC bug
+
+From: Xu Yang <xu.yang_2@nxp.com>
+
+[ Upstream commit 12e6ac69cc7e7d3367599ae26a92a0f9a18bc728 ]
+
+Some NXP processors using ChipIdea USB IP have a bug when frame babble is
+detected.
+
+Issue description:
+In USB camera test, our controller is host in HS mode. In ISOC IN, when
+device sends data across the micro frame, it causes the babble in host
+controller. This will clear the PE bit. In spec, it also requires to set
+the PEC bit and then set the PCI bit. Without the PCI interrupt, the
+software does not know the PE is cleared.
+
+This will add a flag CI_HDRC_HAS_PORTSC_PEC_MISSED to some impacted
+platform datas. And the ehci host driver will assert PEC by SW when
+specific conditions are satisfied.
+
+Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
+Link: https://lore.kernel.org/r/20230809024432.535160-2-xu.yang_2@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/chipidea/ci.h | 1 +
+ drivers/usb/chipidea/ci_hdrc_imx.c | 4 +++-
+ drivers/usb/chipidea/core.c | 2 ++
+ drivers/usb/chipidea/host.c | 1 +
+ include/linux/usb/chipidea.h | 1 +
+ 5 files changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
+index 85a803c135ab3..2ff83911219f8 100644
+--- a/drivers/usb/chipidea/ci.h
++++ b/drivers/usb/chipidea/ci.h
+@@ -253,6 +253,7 @@ struct ci_hdrc {
+ bool id_event;
+ bool b_sess_valid_event;
+ bool imx28_write_fix;
++ bool has_portsc_pec_bug;
+ bool supports_runtime_pm;
+ bool in_lpm;
+ bool wakeup_int;
+diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
+index caa91117ba429..984087bbf3e2b 100644
+--- a/drivers/usb/chipidea/ci_hdrc_imx.c
++++ b/drivers/usb/chipidea/ci_hdrc_imx.c
+@@ -67,11 +67,13 @@ static const struct ci_hdrc_imx_platform_flag imx7d_usb_data = {
+
+ static const struct ci_hdrc_imx_platform_flag imx7ulp_usb_data = {
+ .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
++ CI_HDRC_HAS_PORTSC_PEC_MISSED |
+ CI_HDRC_PMQOS,
+ };
+
+ static const struct ci_hdrc_imx_platform_flag imx8ulp_usb_data = {
+- .flags = CI_HDRC_SUPPORTS_RUNTIME_PM,
++ .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
++ CI_HDRC_HAS_PORTSC_PEC_MISSED,
+ };
+
+ static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
+diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
+index 71f172ecfaabc..b9227f41cf1c0 100644
+--- a/drivers/usb/chipidea/core.c
++++ b/drivers/usb/chipidea/core.c
+@@ -1038,6 +1038,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
+ CI_HDRC_IMX28_WRITE_FIX);
+ ci->supports_runtime_pm = !!(ci->platdata->flags &
+ CI_HDRC_SUPPORTS_RUNTIME_PM);
++ ci->has_portsc_pec_bug = !!(ci->platdata->flags &
++ CI_HDRC_HAS_PORTSC_PEC_MISSED);
+ platform_set_drvdata(pdev, ci);
+
+ ret = hw_device_init(ci, base);
+diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
+index bc3634a54c6b7..3b08c5e811707 100644
+--- a/drivers/usb/chipidea/host.c
++++ b/drivers/usb/chipidea/host.c
+@@ -151,6 +151,7 @@ static int host_start(struct ci_hdrc *ci)
+ ehci->has_hostpc = ci->hw_bank.lpm;
+ ehci->has_tdi_phy_lpm = ci->hw_bank.lpm;
+ ehci->imx28_write_fix = ci->imx28_write_fix;
++ ehci->has_ci_pec_bug = ci->has_portsc_pec_bug;
+
+ priv = (struct ehci_ci_priv *)ehci->priv;
+ priv->reg_vbus = NULL;
+diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
+index ee38835ed77cc..0b4f2d5faa080 100644
+--- a/include/linux/usb/chipidea.h
++++ b/include/linux/usb/chipidea.h
+@@ -63,6 +63,7 @@ struct ci_hdrc_platform_data {
+ #define CI_HDRC_IMX_IS_HSIC BIT(14)
+ #define CI_HDRC_PMQOS BIT(15)
+ #define CI_HDRC_PHY_VBUS_CONTROL BIT(16)
++#define CI_HDRC_HAS_PORTSC_PEC_MISSED BIT(17)
+ enum usb_dr_mode dr_mode;
+ #define CI_HDRC_CONTROLLER_RESET_EVENT 0
+ #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1
+--
+2.40.1
+
--- /dev/null
+From fad8663e60ff308e956b9854d63b3caebec96a79 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Aug 2023 10:44:31 +0800
+Subject: usb: ehci: add workaround for chipidea PORTSC.PEC bug
+
+From: Xu Yang <xu.yang_2@nxp.com>
+
+[ Upstream commit dda4b60ed70bd670eefda081f70c0cb20bbeb1fa ]
+
+Some NXP processor using chipidea IP has a bug when frame babble is
+detected.
+
+As per 4.15.1.1.1 Serial Bus Babble:
+ A babble condition also exists if IN transaction is in progress at
+High-speed SOF2 point. This is called frame babble. The host controller
+must disable the port to which the frame babble is detected.
+
+The USB controller has disabled the port (PE cleared) and has asserted
+USBERRINT when frame babble is detected, but PEC is not asserted.
+Therefore, the SW isn't aware that port has been disabled. Then the
+SW keeps sending packets to this port, but all of the transfers will
+fail.
+
+This workaround will firstly assert PCD by SW when USBERRINT is detected
+and then judge whether port change has really occurred or not by polling
+roothub status. Because the PEC doesn't get asserted in our case, this
+patch will also assert it by SW when specific conditions are satisfied.
+
+Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Link: https://lore.kernel.org/r/20230809024432.535160-1-xu.yang_2@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/ehci-hcd.c | 8 ++++++--
+ drivers/usb/host/ehci-hub.c | 10 +++++++++-
+ drivers/usb/host/ehci.h | 10 ++++++++++
+ 3 files changed, 25 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
+index a1930db0da1c3..802bfafb1012b 100644
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -755,10 +755,14 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
+
+ /* normal [4.15.1.2] or error [4.15.1.1] completion */
+ if (likely ((status & (STS_INT|STS_ERR)) != 0)) {
+- if (likely ((status & STS_ERR) == 0))
++ if (likely ((status & STS_ERR) == 0)) {
+ INCR(ehci->stats.normal);
+- else
++ } else {
++ /* Force to check port status */
++ if (ehci->has_ci_pec_bug)
++ status |= STS_PCD;
+ INCR(ehci->stats.error);
++ }
+ bh = 1;
+ }
+
+diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
+index efe30e3be22f7..1aee392e84927 100644
+--- a/drivers/usb/host/ehci-hub.c
++++ b/drivers/usb/host/ehci-hub.c
+@@ -674,7 +674,8 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
+
+ if ((temp & mask) != 0 || test_bit(i, &ehci->port_c_suspend)
+ || (ehci->reset_done[i] && time_after_eq(
+- jiffies, ehci->reset_done[i]))) {
++ jiffies, ehci->reset_done[i]))
++ || ehci_has_ci_pec_bug(ehci, temp)) {
+ if (i < 7)
+ buf [0] |= 1 << (i + 1);
+ else
+@@ -875,6 +876,13 @@ int ehci_hub_control(
+ if (temp & PORT_PEC)
+ status |= USB_PORT_STAT_C_ENABLE << 16;
+
++ if (ehci_has_ci_pec_bug(ehci, temp)) {
++ status |= USB_PORT_STAT_C_ENABLE << 16;
++ ehci_info(ehci,
++ "PE is cleared by HW port:%d PORTSC:%08x\n",
++ wIndex + 1, temp);
++ }
++
+ if ((temp & PORT_OCC) && (!ignore_oc && !ehci->spurious_oc)){
+ status |= USB_PORT_STAT_C_OVERCURRENT << 16;
+
+diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
+index ad3f13a3eaf1b..5c0e25742e179 100644
+--- a/drivers/usb/host/ehci.h
++++ b/drivers/usb/host/ehci.h
+@@ -207,6 +207,7 @@ struct ehci_hcd { /* one per controller */
+ unsigned has_fsl_port_bug:1; /* FreeScale */
+ unsigned has_fsl_hs_errata:1; /* Freescale HS quirk */
+ unsigned has_fsl_susp_errata:1; /* NXP SUSP quirk */
++ unsigned has_ci_pec_bug:1; /* ChipIdea PEC bug */
+ unsigned big_endian_mmio:1;
+ unsigned big_endian_desc:1;
+ unsigned big_endian_capbase:1;
+@@ -707,6 +708,15 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc)
+ */
+ #define ehci_has_fsl_susp_errata(e) ((e)->has_fsl_susp_errata)
+
++/*
++ * Some Freescale/NXP processors using ChipIdea IP have a bug in which
++ * disabling the port (PE is cleared) does not cause PEC to be asserted
++ * when frame babble is detected.
++ */
++#define ehci_has_ci_pec_bug(e, portsc) \
++ ((e)->has_ci_pec_bug && ((e)->command & CMD_PSE) \
++ && !(portsc & PORT_PEC) && !(portsc & PORT_PE))
++
+ /*
+ * While most USB host controllers implement their registers in
+ * little-endian format, a minority (celleb companion chip) implement
+--
+2.40.1
+
--- /dev/null
+From ea14c429f234ba581ae6a75fa1ef730b49940fef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Jun 2023 16:15:11 +0800
+Subject: usb: gadget: fsl_qe_udc: validate endpoint index for ch9 udc
+
+From: Ma Ke <make_ruc2021@163.com>
+
+[ Upstream commit ce9daa2efc0872a9a68ea51dc8000df05893ef2e ]
+
+We should verify the bound of the array to assure that host
+may not manipulate the index to point past endpoint array.
+
+Signed-off-by: Ma Ke <make_ruc2021@163.com>
+Acked-by: Li Yang <leoyang.li@nxp.com>
+Link: https://lore.kernel.org/r/20230628081511.186850-1-make_ruc2021@163.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/udc/fsl_qe_udc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c
+index 3b1cc8fa30c83..f4e5cbd193b7b 100644
+--- a/drivers/usb/gadget/udc/fsl_qe_udc.c
++++ b/drivers/usb/gadget/udc/fsl_qe_udc.c
+@@ -1959,6 +1959,8 @@ static void ch9getstatus(struct qe_udc *udc, u8 request_type, u16 value,
+ } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_ENDPOINT) {
+ /* Get endpoint status */
+ int pipe = index & USB_ENDPOINT_NUMBER_MASK;
++ if (pipe >= USB_MAX_ENDPOINTS)
++ goto stall;
+ struct qe_ep *target_ep = &udc->eps[pipe];
+ u16 usep;
+
+--
+2.40.1
+
--- /dev/null
+From 5d7742199f5d90f8eb5f704267c5d165e307468f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jul 2023 13:11:07 +0300
+Subject: wifi: ath9k: fix fortify warnings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 810e41cebb6c6e394f2068f839e1a3fc745a5dcc ]
+
+When compiling with gcc 13.1 and CONFIG_FORTIFY_SOURCE=y,
+I've noticed the following:
+
+In function ‘fortify_memcpy_chk’,
+ inlined from ‘ath_tx_complete_aggr’ at drivers/net/wireless/ath/ath9k/xmit.c:556:4,
+ inlined from ‘ath_tx_process_buffer’ at drivers/net/wireless/ath/ath9k/xmit.c:773:3:
+./include/linux/fortify-string.h:529:25: warning: call to ‘__read_overflow2_field’
+declared with attribute warning: detected read beyond size of field (2nd parameter);
+maybe use struct_group()? [-Wattribute-warning]
+ 529 | __read_overflow2_field(q_size_field, size);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In function ‘fortify_memcpy_chk’,
+ inlined from ‘ath_tx_count_frames’ at drivers/net/wireless/ath/ath9k/xmit.c:473:3,
+ inlined from ‘ath_tx_complete_aggr’ at drivers/net/wireless/ath/ath9k/xmit.c:572:2,
+ inlined from ‘ath_tx_process_buffer’ at drivers/net/wireless/ath/ath9k/xmit.c:773:3:
+./include/linux/fortify-string.h:529:25: warning: call to ‘__read_overflow2_field’
+declared with attribute warning: detected read beyond size of field (2nd parameter);
+maybe use struct_group()? [-Wattribute-warning]
+ 529 | __read_overflow2_field(q_size_field, size);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In both cases, the compiler complains on:
+
+memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3);
+
+which is the legal way to copy both 'ba_low' and following 'ba_high'
+members of 'struct ath_tx_status' at once (that is, issue one 8-byte
+'memcpy()' for two 4-byte fields). Since the fortification logic seems
+interprets this trick as an attempt to overread 4-byte 'ba_low', silence
+relevant warnings by using the convenient 'struct_group()' quirk.
+
+Suggested-by: Johannes Berg <johannes@sipsolutions.net>
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230620080855.396851-2-dmantipov@yandex.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/mac.h | 6 ++++--
+ drivers/net/wireless/ath/ath9k/xmit.c | 4 ++--
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
+index af44b33814ddc..f03d792732da7 100644
+--- a/drivers/net/wireless/ath/ath9k/mac.h
++++ b/drivers/net/wireless/ath/ath9k/mac.h
+@@ -115,8 +115,10 @@ struct ath_tx_status {
+ u8 qid;
+ u16 desc_id;
+ u8 tid;
+- u32 ba_low;
+- u32 ba_high;
++ struct_group(ba,
++ u32 ba_low;
++ u32 ba_high;
++ );
+ u32 evm0;
+ u32 evm1;
+ u32 evm2;
+diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
+index ba271a10d4ab1..eeabdd67fbccd 100644
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -462,7 +462,7 @@ static void ath_tx_count_frames(struct ath_softc *sc, struct ath_buf *bf,
+ isaggr = bf_isaggr(bf);
+ if (isaggr) {
+ seq_st = ts->ts_seqnum;
+- memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3);
++ memcpy(ba, &ts->ba, WME_BA_BMP_SIZE >> 3);
+ }
+
+ while (bf) {
+@@ -545,7 +545,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
+ if (isaggr && txok) {
+ if (ts->ts_flags & ATH9K_TX_BA) {
+ seq_st = ts->ts_seqnum;
+- memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3);
++ memcpy(ba, &ts->ba, WME_BA_BMP_SIZE >> 3);
+ } else {
+ /*
+ * AR5416 can become deaf/mute when BA
+--
+2.40.1
+
--- /dev/null
+From e26e5a3c131615ef4090c8cf70e7072e58debd7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Jul 2023 12:04:02 +0800
+Subject: wifi: ath9k: fix printk specifier
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dongliang Mu <dzm91@hust.edu.cn>
+
+[ Upstream commit 061115fbfb2ce5870c9a004d68dc63138c07c782 ]
+
+Smatch reports:
+
+ath_pci_probe() warn: argument 4 to %lx specifier is cast from pointer
+ath_ahb_probe() warn: argument 4 to %lx specifier is cast from pointer
+
+Fix it by modifying %lx to %p in the printk format string.
+
+Note that with this change, the pointer address will be printed as a
+hashed value by default. This is appropriate because the kernel
+should not leak kernel pointers to user space in an informational
+message. If someone wants to see the real address for debugging
+purposes, this can be achieved with the no_hash_pointers kernel option.
+
+Signed-off-by: Dongliang Mu <dzm91@hust.edu.cn>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230723040403.296723-1-dzm91@hust.edu.cn
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/ahb.c | 4 ++--
+ drivers/net/wireless/ath/ath9k/pci.c | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
+index 9cd12b20b18d8..9bfaadfa6c009 100644
+--- a/drivers/net/wireless/ath/ath9k/ahb.c
++++ b/drivers/net/wireless/ath/ath9k/ahb.c
+@@ -132,8 +132,8 @@ static int ath_ahb_probe(struct platform_device *pdev)
+
+ ah = sc->sc_ah;
+ ath9k_hw_name(ah, hw_name, sizeof(hw_name));
+- wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
+- hw_name, (unsigned long)mem, irq);
++ wiphy_info(hw->wiphy, "%s mem=0x%p, irq=%d\n",
++ hw_name, mem, irq);
+
+ return 0;
+
+diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
+index a074e23013c58..f0e3901e8182a 100644
+--- a/drivers/net/wireless/ath/ath9k/pci.c
++++ b/drivers/net/wireless/ath/ath9k/pci.c
+@@ -988,8 +988,8 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ sc->sc_ah->msi_reg = 0;
+
+ ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name));
+- wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
+- hw_name, (unsigned long)sc->mem, pdev->irq);
++ wiphy_info(hw->wiphy, "%s mem=0x%p, irq=%d\n",
++ hw_name, sc->mem, pdev->irq);
+
+ return 0;
+
+--
+2.40.1
+
--- /dev/null
+From 79c450b88bf4b5203839e9968696a5669229410f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Aug 2023 18:32:03 +0200
+Subject: wifi: cfg80211: ocb: don't leave if not joined
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit abc76cf552e13cfa88a204b362a86b0e08e95228 ]
+
+If there's no OCB state, don't ask the driver/mac80211 to
+leave, since that's just confusing. Since set/clear the
+chandef state, that's a simple check.
+
+Reported-by: syzbot+09d1cd2f71e6dd3bfd2c@syzkaller.appspotmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/ocb.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/wireless/ocb.c b/net/wireless/ocb.c
+index 27a1732264f95..29afaf3da54f3 100644
+--- a/net/wireless/ocb.c
++++ b/net/wireless/ocb.c
+@@ -68,6 +68,9 @@ int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev,
+ if (!rdev->ops->leave_ocb)
+ return -EOPNOTSUPP;
+
++ if (!wdev->u.ocb.chandef.chan)
++ return -ENOTCONN;
++
+ err = rdev_leave_ocb(rdev, dev);
+ if (!err)
+ memset(&wdev->u.ocb.chandef, 0, sizeof(wdev->u.ocb.chandef));
+--
+2.40.1
+
--- /dev/null
+From 0dfcaa514d4ae1583ca96c68db800e1dd10f1f79 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Aug 2023 18:09:00 +0200
+Subject: wifi: cfg80211: reject auth/assoc to AP with our address
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 5d4e04bf3a0f098bd9033de3a5291810fa14c7a6 ]
+
+If the AP uses our own address as its MLD address or BSSID, then
+clearly something's wrong. Reject such connections so we don't
+try and fail later.
+
+Reported-by: syzbot+2676771ed06a6df166ad@syzkaller.appspotmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/mlme.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
+index 581df7f4c5240..e7fa0608341d8 100644
+--- a/net/wireless/mlme.c
++++ b/net/wireless/mlme.c
+@@ -277,6 +277,11 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
+ ether_addr_equal(req->bss->bssid, wdev->u.client.connected_addr))
+ return -EALREADY;
+
++ if (ether_addr_equal(req->bss->bssid, dev->dev_addr) ||
++ (req->link_id >= 0 &&
++ ether_addr_equal(req->ap_mld_addr, dev->dev_addr)))
++ return -EINVAL;
++
+ return rdev_auth(rdev, dev, req);
+ }
+
+@@ -331,6 +336,9 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
+ if (req->links[i].bss == req->links[j].bss)
+ return -EINVAL;
+ }
++
++ if (ether_addr_equal(req->links[i].bss->bssid, dev->dev_addr))
++ return -EINVAL;
+ }
+
+ if (wdev->connected &&
+@@ -338,6 +346,11 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
+ !ether_addr_equal(wdev->u.client.connected_addr, req->prev_bssid)))
+ return -EALREADY;
+
++ if ((req->bss && ether_addr_equal(req->bss->bssid, dev->dev_addr)) ||
++ (req->link_id >= 0 &&
++ ether_addr_equal(req->ap_mld_addr, dev->dev_addr)))
++ return -EINVAL;
++
+ cfg80211_oper_and_ht_capa(&req->ht_capa_mask,
+ rdev->wiphy.ht_capa_mod_mask);
+ cfg80211_oper_and_vht_capa(&req->vht_capa_mask,
+--
+2.40.1
+
--- /dev/null
+From e95adf46e98b312b75ef0a7d7becb5a5da75b222 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Aug 2023 18:41:32 +0200
+Subject: wifi: mac80211: check for station first in client probe
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 67dfa589aa8806c7959cbca2f4613b8d41c75a06 ]
+
+When probing a client, first check if we have it, and then
+check for the channel context, otherwise you can trigger
+the warning there easily by probing when the AP isn't even
+started yet. Since a client existing means the AP is also
+operating, we can then keep the warning.
+
+Also simplify the moved code a bit.
+
+Reported-by: syzbot+999fac712d84878a7379@syzkaller.appspotmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/cfg.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 23a44edcb11f7..cf3453b532d67 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -3991,19 +3991,20 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
+ mutex_lock(&local->mtx);
+
+ rcu_read_lock();
++ sta = sta_info_get_bss(sdata, peer);
++ if (!sta) {
++ ret = -ENOLINK;
++ goto unlock;
++ }
++
++ qos = sta->sta.wme;
++
+ chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
+ if (WARN_ON(!chanctx_conf)) {
+ ret = -EINVAL;
+ goto unlock;
+ }
+ band = chanctx_conf->def.chan->band;
+- sta = sta_info_get_bss(sdata, peer);
+- if (sta) {
+- qos = sta->sta.wme;
+- } else {
+- ret = -ENOLINK;
+- goto unlock;
+- }
+
+ if (qos) {
+ fc = cpu_to_le16(IEEE80211_FTYPE_DATA |
+--
+2.40.1
+
--- /dev/null
+From b12fbaaa6c31af1eaacadde675a758e652eb57a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Aug 2023 17:51:05 +0200
+Subject: wifi: mac80211: check S1G action frame size
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 19e4a47ee74718a22e963e8a647c8c3bfe8bb05c ]
+
+Before checking the action code, check that it even
+exists in the frame.
+
+Reported-by: syzbot+be9c824e6f269d608288@syzkaller.appspotmail.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/rx.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 55dc0610e8633..c4c80037df91d 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -3625,6 +3625,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
+ break;
+ goto queue;
+ case WLAN_CATEGORY_S1G:
++ if (len < offsetofend(typeof(*mgmt),
++ u.action.u.s1g.action_code))
++ break;
++
+ switch (mgmt->u.action.u.s1g.action_code) {
+ case WLAN_S1G_TWT_SETUP:
+ case WLAN_S1G_TWT_TEARDOWN:
+--
+2.40.1
+
--- /dev/null
+From 08333a2aec2785e083c8362f0715dcb4772f79de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Aug 2023 21:28:01 +0200
+Subject: wifi: mac80211_hwsim: drop short frames
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit fba360a047d5eeeb9d4b7c3a9b1c8308980ce9a6 ]
+
+While technically some control frames like ACK are shorter and
+end after Address 1, such frames shouldn't be forwarded through
+wmediumd or similar userspace, so require the full 3-address
+header to avoid accessing invalid memory if shorter frames are
+passed in.
+
+Reported-by: syzbot+b2645b5bf1512b81fa22@syzkaller.appspotmail.com
+Reviewed-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mac80211_hwsim.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
+index da5c355405f68..db70cef854bc4 100644
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -4906,14 +4906,15 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
+ frame_data_len = nla_len(info->attrs[HWSIM_ATTR_FRAME]);
+ frame_data = (void *)nla_data(info->attrs[HWSIM_ATTR_FRAME]);
+
++ if (frame_data_len < sizeof(struct ieee80211_hdr_3addr) ||
++ frame_data_len > IEEE80211_MAX_DATA_LEN)
++ goto err;
++
+ /* Allocate new skb here */
+ skb = alloc_skb(frame_data_len, GFP_KERNEL);
+ if (skb == NULL)
+ goto err;
+
+- if (frame_data_len > IEEE80211_MAX_DATA_LEN)
+- goto err;
+-
+ /* Copy the data */
+ skb_put_data(skb, frame_data, frame_data_len);
+
+--
+2.40.1
+
--- /dev/null
+From af58f417bfd074bb55468fe7f06eb3daa754643a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jun 2023 11:51:01 +0300
+Subject: wifi: mwifiex: fix fortify warning
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit dcce94b80a954a8968ff29fafcfb066d6197fa9a ]
+
+When compiling with gcc 13.1 and CONFIG_FORTIFY_SOURCE=y,
+I've noticed the following:
+
+In function ‘fortify_memcpy_chk’,
+ inlined from ‘mwifiex_construct_tdls_action_frame’ at drivers/net/wireless/marvell/mwifiex/tdls.c:765:3,
+ inlined from ‘mwifiex_send_tdls_action_frame’ at drivers/net/wireless/marvell/mwifiex/tdls.c:856:6:
+./include/linux/fortify-string.h:529:25: warning: call to ‘__read_overflow2_field’
+declared with attribute warning: detected read beyond size of field (2nd parameter);
+maybe use struct_group()? [-Wattribute-warning]
+ 529 | __read_overflow2_field(q_size_field, size);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The compiler actually complains on:
+
+memmove(pos + ETH_ALEN, &mgmt->u.action.category,
+ sizeof(mgmt->u.action.u.tdls_discover_resp));
+
+and it happens because the fortification logic interprets this
+as an attempt to overread 1-byte 'u.action.category' member of
+'struct ieee80211_mgmt'. To silence this warning, it's enough
+to pass an address of 'u.action' itself instead of an address
+of its first member.
+
+This also fixes an improper usage of 'sizeof()'. Since 'skb' is
+extended with 'sizeof(mgmt->u.action.u.tdls_discover_resp) + 1'
+bytes (where 1 is actually 'sizeof(mgmt->u.action.category)'),
+I assume that the same number of bytes should be copied.
+
+Suggested-by: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Reviewed-by: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20230629085115.180499-2-dmantipov@yandex.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/marvell/mwifiex/tdls.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/marvell/mwifiex/tdls.c b/drivers/net/wireless/marvell/mwifiex/tdls.c
+index 97bb87c3676bb..6c60621b6cccb 100644
+--- a/drivers/net/wireless/marvell/mwifiex/tdls.c
++++ b/drivers/net/wireless/marvell/mwifiex/tdls.c
+@@ -735,6 +735,7 @@ mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv,
+ int ret;
+ u16 capab;
+ struct ieee80211_ht_cap *ht_cap;
++ unsigned int extra;
+ u8 radio, *pos;
+
+ capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap;
+@@ -753,7 +754,10 @@ mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv,
+
+ switch (action_code) {
+ case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
+- skb_put(skb, sizeof(mgmt->u.action.u.tdls_discover_resp) + 1);
++ /* See the layout of 'struct ieee80211_mgmt'. */
++ extra = sizeof(mgmt->u.action.u.tdls_discover_resp) +
++ sizeof(mgmt->u.action.category);
++ skb_put(skb, extra);
+ mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
+ mgmt->u.action.u.tdls_discover_resp.action_code =
+ WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
+@@ -762,8 +766,7 @@ mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv,
+ mgmt->u.action.u.tdls_discover_resp.capability =
+ cpu_to_le16(capab);
+ /* move back for addr4 */
+- memmove(pos + ETH_ALEN, &mgmt->u.action.category,
+- sizeof(mgmt->u.action.u.tdls_discover_resp));
++ memmove(pos + ETH_ALEN, &mgmt->u.action, extra);
+ /* init address 4 */
+ eth_broadcast_addr(pos);
+
+--
+2.40.1
+
--- /dev/null
+From 7a4afa4121291d5e7b07d2d269a8eeba83e7ae5a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jun 2023 12:36:55 +0300
+Subject: wifi: wil6210: fix fortify warnings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 1ad8237e971630c66a1a6194491e0837b64d00e0 ]
+
+When compiling with gcc 13.1 and CONFIG_FORTIFY_SOURCE=y,
+I've noticed the following:
+
+In function ‘fortify_memcpy_chk’,
+ inlined from ‘wil_rx_crypto_check_edma’ at drivers/net/wireless/ath/wil6210/txrx_edma.c:566:2:
+./include/linux/fortify-string.h:529:25: warning: call to ‘__read_overflow2_field’
+declared with attribute warning: detected read beyond size of field (2nd parameter);
+maybe use struct_group()? [-Wattribute-warning]
+ 529 | __read_overflow2_field(q_size_field, size);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+where the compiler complains on:
+
+const u8 *pn;
+...
+pn = (u8 *)&st->ext.pn_15_0;
+...
+memcpy(cc->pn, pn, IEEE80211_GCMP_PN_LEN);
+
+and:
+
+In function ‘fortify_memcpy_chk’,
+ inlined from ‘wil_rx_crypto_check’ at drivers/net/wireless/ath/wil6210/txrx.c:684:2:
+./include/linux/fortify-string.h:529:25: warning: call to ‘__read_overflow2_field’
+declared with attribute warning: detected read beyond size of field (2nd parameter);
+maybe use struct_group()? [-Wattribute-warning]
+ 529 | __read_overflow2_field(q_size_field, size);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+where the compiler complains on:
+
+const u8 *pn = (u8 *)&d->mac.pn_15_0;
+...
+memcpy(cc->pn, pn, IEEE80211_GCMP_PN_LEN);
+
+In both cases, the fortification logic interprets 'memcpy()' as 6-byte
+overread of 2-byte field 'pn_15_0' of 'struct wil_rx_status_extension'
+and 'pn_15_0' of 'struct vring_rx_mac', respectively. To silence
+these warnings, last two fields of the aforementioned structures
+are grouped using 'struct_group_attr(pn, __packed' quirk.
+
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://lore.kernel.org/r/20230621093711.80118-1-dmantipov@yandex.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/wil6210/txrx.c | 2 +-
+ drivers/net/wireless/ath/wil6210/txrx.h | 6 ++++--
+ drivers/net/wireless/ath/wil6210/txrx_edma.c | 2 +-
+ drivers/net/wireless/ath/wil6210/txrx_edma.h | 6 ++++--
+ 4 files changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
+index 237cbd5c5060b..f29ac6de71399 100644
+--- a/drivers/net/wireless/ath/wil6210/txrx.c
++++ b/drivers/net/wireless/ath/wil6210/txrx.c
+@@ -666,7 +666,7 @@ static int wil_rx_crypto_check(struct wil6210_priv *wil, struct sk_buff *skb)
+ struct wil_tid_crypto_rx *c = mc ? &s->group_crypto_rx :
+ &s->tid_crypto_rx[tid];
+ struct wil_tid_crypto_rx_single *cc = &c->key_id[key_id];
+- const u8 *pn = (u8 *)&d->mac.pn_15_0;
++ const u8 *pn = (u8 *)&d->mac.pn;
+
+ if (!cc->key_set) {
+ wil_err_ratelimited(wil,
+diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h
+index 1ae1bec1b97f1..689f68d89a440 100644
+--- a/drivers/net/wireless/ath/wil6210/txrx.h
++++ b/drivers/net/wireless/ath/wil6210/txrx.h
+@@ -343,8 +343,10 @@ struct vring_rx_mac {
+ u32 d0;
+ u32 d1;
+ u16 w4;
+- u16 pn_15_0;
+- u32 pn_47_16;
++ struct_group_attr(pn, __packed,
++ u16 pn_15_0;
++ u32 pn_47_16;
++ );
+ } __packed;
+
+ /* Rx descriptor - DMA part
+diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c
+index 201c8c35e0c9e..1ba1f21ebea26 100644
+--- a/drivers/net/wireless/ath/wil6210/txrx_edma.c
++++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c
+@@ -548,7 +548,7 @@ static int wil_rx_crypto_check_edma(struct wil6210_priv *wil,
+ s = &wil->sta[cid];
+ c = mc ? &s->group_crypto_rx : &s->tid_crypto_rx[tid];
+ cc = &c->key_id[key_id];
+- pn = (u8 *)&st->ext.pn_15_0;
++ pn = (u8 *)&st->ext.pn;
+
+ if (!cc->key_set) {
+ wil_err_ratelimited(wil,
+diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.h b/drivers/net/wireless/ath/wil6210/txrx_edma.h
+index c736f7413a35f..ee90e225bb050 100644
+--- a/drivers/net/wireless/ath/wil6210/txrx_edma.h
++++ b/drivers/net/wireless/ath/wil6210/txrx_edma.h
+@@ -330,8 +330,10 @@ struct wil_rx_status_extension {
+ u32 d0;
+ u32 d1;
+ __le16 seq_num; /* only lower 12 bits */
+- u16 pn_15_0;
+- u32 pn_47_16;
++ struct_group_attr(pn, __packed,
++ u16 pn_15_0;
++ u32 pn_47_16;
++ );
+ } __packed;
+
+ struct wil_rx_status_extended {
+--
+2.40.1
+
--- /dev/null
+From e6e692fe5d57ab85e13aace38b5f6f4092979c58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Sep 2023 10:02:21 +0300
+Subject: x86/boot/compressed: Reserve more memory for page tables
+
+From: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+
+[ Upstream commit f530ee95b72e77b09c141c4b1a4b94d1199ffbd9 ]
+
+The decompressor has a hard limit on the number of page tables it can
+allocate. This limit is defined at compile-time and will cause boot
+failure if it is reached.
+
+The kernel is very strict and calculates the limit precisely for the
+worst-case scenario based on the current configuration. However, it is
+easy to forget to adjust the limit when a new use-case arises. The
+worst-case scenario is rarely encountered during sanity checks.
+
+In the case of enabling 5-level paging, a use-case was overlooked. The
+limit needs to be increased by one to accommodate the additional level.
+This oversight went unnoticed until Aaron attempted to run the kernel
+via kexec with 5-level paging and unaccepted memory enabled.
+
+Update wost-case calculations to include 5-level paging.
+
+To address this issue, let's allocate some extra space for page tables.
+128K should be sufficient for any use-case. The logic can be simplified
+by using a single value for all kernel configurations.
+
+[ Also add a warning, should this memory run low - by Dave Hansen. ]
+
+Fixes: 34bbb0009f3b ("x86/boot/compressed: Enable 5-level paging during decompression stage")
+Reported-by: Aaron Lu <aaron.lu@intel.com>
+Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/r/20230915070221.10266-1-kirill.shutemov@linux.intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/boot/compressed/ident_map_64.c | 8 +++++
+ arch/x86/include/asm/boot.h | 45 +++++++++++++++++--------
+ 2 files changed, 39 insertions(+), 14 deletions(-)
+
+diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c
+index 321a5011042d4..b4155273df891 100644
+--- a/arch/x86/boot/compressed/ident_map_64.c
++++ b/arch/x86/boot/compressed/ident_map_64.c
+@@ -67,6 +67,14 @@ static void *alloc_pgt_page(void *context)
+ return NULL;
+ }
+
++ /* Consumed more tables than expected? */
++ if (pages->pgt_buf_offset == BOOT_PGT_SIZE_WARN) {
++ debug_putstr("pgt_buf running low in " __FILE__ "\n");
++ debug_putstr("Need to raise BOOT_PGT_SIZE?\n");
++ debug_putaddr(pages->pgt_buf_offset);
++ debug_putaddr(pages->pgt_buf_size);
++ }
++
+ entry = pages->pgt_buf + pages->pgt_buf_offset;
+ pages->pgt_buf_offset += PAGE_SIZE;
+
+diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h
+index 9191280d9ea31..215d37f7dde8a 100644
+--- a/arch/x86/include/asm/boot.h
++++ b/arch/x86/include/asm/boot.h
+@@ -40,23 +40,40 @@
+ #ifdef CONFIG_X86_64
+ # define BOOT_STACK_SIZE 0x4000
+
++/*
++ * Used by decompressor's startup_32() to allocate page tables for identity
++ * mapping of the 4G of RAM in 4-level paging mode:
++ * - 1 level4 table;
++ * - 1 level3 table;
++ * - 4 level2 table that maps everything with 2M pages;
++ *
++ * The additional level5 table needed for 5-level paging is allocated from
++ * trampoline_32bit memory.
++ */
+ # define BOOT_INIT_PGT_SIZE (6*4096)
+-# ifdef CONFIG_RANDOMIZE_BASE
++
+ /*
+- * Assuming all cross the 512GB boundary:
+- * 1 page for level4
+- * (2+2)*4 pages for kernel, param, cmd_line, and randomized kernel
+- * 2 pages for first 2M (video RAM: CONFIG_X86_VERBOSE_BOOTUP).
+- * Total is 19 pages.
++ * Total number of page tables kernel_add_identity_map() can allocate,
++ * including page tables consumed by startup_32().
++ *
++ * Worst-case scenario:
++ * - 5-level paging needs 1 level5 table;
++ * - KASLR needs to map kernel, boot_params, cmdline and randomized kernel,
++ * assuming all of them cross 256T boundary:
++ * + 4*2 level4 table;
++ * + 4*2 level3 table;
++ * + 4*2 level2 table;
++ * - X86_VERBOSE_BOOTUP needs to map the first 2M (video RAM):
++ * + 1 level4 table;
++ * + 1 level3 table;
++ * + 1 level2 table;
++ * Total: 28 tables
++ *
++ * Add 4 spare table in case decompressor touches anything beyond what is
++ * accounted above. Warn if it happens.
+ */
+-# ifdef CONFIG_X86_VERBOSE_BOOTUP
+-# define BOOT_PGT_SIZE (19*4096)
+-# else /* !CONFIG_X86_VERBOSE_BOOTUP */
+-# define BOOT_PGT_SIZE (17*4096)
+-# endif
+-# else /* !CONFIG_RANDOMIZE_BASE */
+-# define BOOT_PGT_SIZE BOOT_INIT_PGT_SIZE
+-# endif
++# define BOOT_PGT_SIZE_WARN (28*4096)
++# define BOOT_PGT_SIZE (32*4096)
+
+ #else /* !CONFIG_X86_64 */
+ # define BOOT_STACK_SIZE 0x1000
+--
+2.40.1
+
--- /dev/null
+From 0c53b75d20189985b1312a474a26120e9ae77d06 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Aug 2023 12:55:46 +0200
+Subject: x86/ibt: Suppress spurious ENDBR
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit 25e73b7e3f72a25aa30cbb2eecb49036e0acf066 ]
+
+It was reported that under certain circumstances GCC emits ENDBR
+instructions for _THIS_IP_ usage. Specifically, when it appears at the
+start of a basic block -- but not elsewhere.
+
+Since _THIS_IP_ is never used for control flow, these ENDBR
+instructions are completely superfluous. Override the _THIS_IP_
+definition for x86_64 to avoid this.
+
+Less ENDBR instructions is better.
+
+Fixes: 156ff4a544ae ("x86/ibt: Base IBT bits")
+Reported-by: David Kaplan <David.Kaplan@amd.com>
+Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Link: https://lore.kernel.org/r/20230802110323.016197440@infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/linkage.h | 8 ++++++++
+ include/linux/instruction_pointer.h | 5 +++++
+ 2 files changed, 13 insertions(+)
+
+diff --git a/arch/x86/include/asm/linkage.h b/arch/x86/include/asm/linkage.h
+index f484d656d34ee..3a0282a6a55df 100644
+--- a/arch/x86/include/asm/linkage.h
++++ b/arch/x86/include/asm/linkage.h
+@@ -8,6 +8,14 @@
+ #undef notrace
+ #define notrace __attribute__((no_instrument_function))
+
++#ifdef CONFIG_64BIT
++/*
++ * The generic version tends to create spurious ENDBR instructions under
++ * certain conditions.
++ */
++#define _THIS_IP_ ({ unsigned long __here; asm ("lea 0(%%rip), %0" : "=r" (__here)); __here; })
++#endif
++
+ #ifdef CONFIG_X86_32
+ #define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
+ #endif /* CONFIG_X86_32 */
+diff --git a/include/linux/instruction_pointer.h b/include/linux/instruction_pointer.h
+index cda1f706eaeb1..aa0b3ffea9353 100644
+--- a/include/linux/instruction_pointer.h
++++ b/include/linux/instruction_pointer.h
+@@ -2,7 +2,12 @@
+ #ifndef _LINUX_INSTRUCTION_POINTER_H
+ #define _LINUX_INSTRUCTION_POINTER_H
+
++#include <asm/linkage.h>
++
+ #define _RET_IP_ (unsigned long)__builtin_return_address(0)
++
++#ifndef _THIS_IP_
+ #define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; })
++#endif
+
+ #endif /* _LINUX_INSTRUCTION_POINTER_H */
+--
+2.40.1
+
--- /dev/null
+From 14761593cf20e4f3d1fb083a2f79c753fde8b78f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Sep 2023 10:01:38 -0700
+Subject: x86/purgatory: Remove LTO flags
+
+From: Song Liu <song@kernel.org>
+
+[ Upstream commit 75b2f7e4c9e0fd750a5a27ca9736d1daa7a3762a ]
+
+-flto* implies -ffunction-sections. With LTO enabled, ld.lld generates
+multiple .text sections for purgatory.ro:
+
+ $ readelf -S purgatory.ro | grep " .text"
+ [ 1] .text PROGBITS 0000000000000000 00000040
+ [ 7] .text.purgatory PROGBITS 0000000000000000 000020e0
+ [ 9] .text.warn PROGBITS 0000000000000000 000021c0
+ [13] .text.sha256_upda PROGBITS 0000000000000000 000022f0
+ [15] .text.sha224_upda PROGBITS 0000000000000000 00002be0
+ [17] .text.sha256_fina PROGBITS 0000000000000000 00002bf0
+ [19] .text.sha224_fina PROGBITS 0000000000000000 00002cc0
+
+This causes WARNING from kexec_purgatory_setup_sechdrs():
+
+ WARNING: CPU: 26 PID: 110894 at kernel/kexec_file.c:919
+ kexec_load_purgatory+0x37f/0x390
+
+Fix this by disabling LTO for purgatory.
+
+[ AFAICT, x86 is the only arch that supports LTO and purgatory. ]
+
+We could also fix this with an explicit linker script to rejoin .text.*
+sections back into .text. However, given the benefit of LTOing purgatory
+is small, simply disable the production of more .text.* sections for now.
+
+Fixes: b33fff07e3e3 ("x86, build: allow LTO to be selected")
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
+Reviewed-by: Sami Tolvanen <samitolvanen@google.com>
+Link: https://lore.kernel.org/r/20230914170138.995606-1-song@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/purgatory/Makefile | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile
+index 42abd6af11984..d28e0987aa85b 100644
+--- a/arch/x86/purgatory/Makefile
++++ b/arch/x86/purgatory/Makefile
+@@ -19,6 +19,10 @@ CFLAGS_sha256.o := -D__DISABLE_EXPORTS
+ # optimization flags.
+ KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%,$(KBUILD_CFLAGS))
+
++# When LTO is enabled, llvm emits many text sections, which is not supported
++# by kexec. Remove -flto=* flags.
++KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS))
++
+ # When linking purgatory.ro with -r unresolved symbols are not checked,
+ # also link a purgatory.chk binary without -r to check for unresolved symbols.
+ PURGATORY_LDFLAGS := -e purgatory_start -z nodefaultlib
+--
+2.40.1
+