--- /dev/null
+From 92d1448c2dea41c86da959246535438499277b94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Mar 2022 13:39:03 +0100
+Subject: ACPI: bus: Avoid using CPPC if not supported by firmware
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit c42fa24b44751c62c86e98430ef915c0609a2ab8 ]
+
+If the platform firmware indicates that it does not support CPPC by
+clearing the OSC_SB_CPC_SUPPORT and OSC_SB_CPCV2_SUPPORT bits in the
+platform _OSC capabilities mask, avoid attempting to evaluate _CPC
+which may fail in that case.
+
+Because the OSC_SB_CPC_SUPPORT and OSC_SB_CPCV2_SUPPORT bits are only
+added to the supported platform capabilities mask on x86, when
+X86_FEATURE_HWP is supported, allow _CPC to be evaluated regardless
+in the other cases.
+
+Link: https://lore.kernel.org/linux-acpi/CAJZ5v0i=ecAksq0TV+iLVObm-=fUfdqPABzzkgm9K6KxO1ZCcg@mail.gmail.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Tested-by: Mario Limonciello <mario.limonciello@amd.com>
+Acked-by: Huang Rui <ray.huang@amd.com>
+Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Stable-dep-of: 60949b7b8054 ("ACPI: CPPC: Fix MASK_VAL() usage")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/bus.c | 8 ++++++++
+ drivers/acpi/cppc_acpi.c | 3 +++
+ include/linux/acpi.h | 1 +
+ 3 files changed, 12 insertions(+)
+
+diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
+index 7774b603a7962..9bc5bc5bc359b 100644
+--- a/drivers/acpi/bus.c
++++ b/drivers/acpi/bus.c
+@@ -283,6 +283,8 @@ EXPORT_SYMBOL_GPL(osc_pc_lpi_support_confirmed);
+ bool osc_sb_native_usb4_support_confirmed;
+ EXPORT_SYMBOL_GPL(osc_sb_native_usb4_support_confirmed);
+
++bool osc_sb_cppc_not_supported;
++
+ static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48";
+ static void acpi_bus_osc_negotiate_platform_control(void)
+ {
+@@ -338,6 +340,12 @@ static void acpi_bus_osc_negotiate_platform_control(void)
+ return;
+ }
+
++#ifdef CONFIG_X86
++ if (boot_cpu_has(X86_FEATURE_HWP))
++ osc_sb_cppc_not_supported = !(capbuf_ret[OSC_SUPPORT_DWORD] &
++ (OSC_SB_CPC_SUPPORT | OSC_SB_CPCV2_SUPPORT));
++#endif
++
+ /*
+ * Now run _OSC again with query flag clear and with the caps
+ * supported by both the OS and the platform.
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 6dcce036adb9c..02cec9eba937f 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -673,6 +673,9 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
+ acpi_status status;
+ int ret = -EFAULT;
+
++ if (osc_sb_cppc_not_supported)
++ return -ENODEV;
++
+ /* Parse the ACPI _CPC table for this CPU. */
+ status = acpi_evaluate_object_typed(handle, "_CPC", NULL, &output,
+ ACPI_TYPE_PACKAGE);
+diff --git a/include/linux/acpi.h b/include/linux/acpi.h
+index a23a5aea9c817..42f58a54dff09 100644
+--- a/include/linux/acpi.h
++++ b/include/linux/acpi.h
+@@ -561,6 +561,7 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context);
+ extern bool osc_sb_apei_support_acked;
+ extern bool osc_pc_lpi_support_confirmed;
+ extern bool osc_sb_native_usb4_support_confirmed;
++extern bool osc_sb_cppc_not_supported;
+
+ /* USB4 Capabilities */
+ #define OSC_USB_USB3_TUNNELING 0x00000001
+--
+2.43.0
+
--- /dev/null
+From cea6a5b4706ec67bda9470cb9ab05f9e23deab98 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Aug 2024 12:16:44 +0200
+Subject: ACPI: CPPC: Fix MASK_VAL() usage
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Clément Léger <cleger@rivosinc.com>
+
+[ Upstream commit 60949b7b805424f21326b450ca4f1806c06d982e ]
+
+MASK_VAL() was added as a way to handle bit_offset and bit_width for
+registers located in system memory address space. However, while suited
+for reading, it does not work for writing and result in corrupted
+registers when writing values with bit_offset > 0. Moreover, when a
+register is collocated with another one at the same address but with a
+different mask, the current code results in the other registers being
+overwritten with 0s. The write procedure for SYSTEM_MEMORY registers
+should actually read the value, mask it, update it and write it with the
+updated value. Moreover, since registers can be located in the same
+word, we must take care of locking the access before doing it. We should
+potentially use a global lock since we don't know in if register
+addresses aren't shared with another _CPC package but better not
+encourage vendors to do so. Assume that registers can use the same word
+inside a _CPC package and thus, use a per _CPC package lock.
+
+Fixes: 2f4a4d63a193 ("ACPI: CPPC: Use access_width over bit_width for system memory accesses")
+Signed-off-by: Clément Léger <cleger@rivosinc.com>
+Link: https://patch.msgid.link/20240826101648.95654-1-cleger@rivosinc.com
+[ rjw: Dropped redundant semicolon ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 43 ++++++++++++++++++++++++++++++++++++----
+ include/acpi/cppc_acpi.h | 2 ++
+ 2 files changed, 41 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 02cec9eba937f..8d14e6c705357 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -165,8 +165,11 @@ show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time);
+ #define GET_BIT_WIDTH(reg) ((reg)->access_width ? (8 << ((reg)->access_width - 1)) : (reg)->bit_width)
+
+ /* Shift and apply the mask for CPC reads/writes */
+-#define MASK_VAL(reg, val) (((val) >> (reg)->bit_offset) & \
++#define MASK_VAL_READ(reg, val) (((val) >> (reg)->bit_offset) & \
+ GENMASK(((reg)->bit_width) - 1, 0))
++#define MASK_VAL_WRITE(reg, prev_val, val) \
++ ((((val) & GENMASK(((reg)->bit_width) - 1, 0)) << (reg)->bit_offset) | \
++ ((prev_val) & ~(GENMASK(((reg)->bit_width) - 1, 0) << (reg)->bit_offset))) \
+
+ static ssize_t show_feedback_ctrs(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+@@ -810,6 +813,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
+
+ /* Store CPU Logical ID */
+ cpc_ptr->cpu_id = pr->id;
++ spin_lock_init(&cpc_ptr->rmw_lock);
+
+ /* Parse PSD data for this CPU */
+ ret = acpi_get_psd(cpc_ptr, handle);
+@@ -1002,7 +1006,7 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val)
+ }
+
+ if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
+- *val = MASK_VAL(reg, *val);
++ *val = MASK_VAL_READ(reg, *val);
+
+ return ret_val;
+ }
+@@ -1011,9 +1015,11 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
+ {
+ int ret_val = 0;
+ int size;
++ u64 prev_val;
+ void __iomem *vaddr = NULL;
+ int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
+ struct cpc_reg *reg = ®_res->cpc_entry.reg;
++ struct cpc_desc *cpc_desc;
+
+ size = GET_BIT_WIDTH(reg);
+
+@@ -1034,8 +1040,34 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
+ return acpi_os_write_memory((acpi_physical_address)reg->address,
+ val, size);
+
+- if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
+- val = MASK_VAL(reg, val);
++ if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
++ cpc_desc = per_cpu(cpc_desc_ptr, cpu);
++ if (!cpc_desc) {
++ pr_debug("No CPC descriptor for CPU:%d\n", cpu);
++ return -ENODEV;
++ }
++
++ spin_lock(&cpc_desc->rmw_lock);
++ switch (size) {
++ case 8:
++ prev_val = readb_relaxed(vaddr);
++ break;
++ case 16:
++ prev_val = readw_relaxed(vaddr);
++ break;
++ case 32:
++ prev_val = readl_relaxed(vaddr);
++ break;
++ case 64:
++ prev_val = readq_relaxed(vaddr);
++ break;
++ default:
++ spin_unlock(&cpc_desc->rmw_lock);
++ return -EFAULT;
++ }
++ val = MASK_VAL_WRITE(reg, prev_val, val);
++ val |= prev_val;
++ }
+
+ switch (size) {
+ case 8:
+@@ -1062,6 +1094,9 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
+ break;
+ }
+
++ if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
++ spin_unlock(&cpc_desc->rmw_lock);
++
+ return ret_val;
+ }
+
+diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
+index 6b14414b9ec12..0fed87e2a8959 100644
+--- a/include/acpi/cppc_acpi.h
++++ b/include/acpi/cppc_acpi.h
+@@ -64,6 +64,8 @@ struct cpc_desc {
+ int cpu_id;
+ int write_cmd_status;
+ int write_cmd_id;
++ /* Lock used for RMW operations in cpc_write() */
++ spinlock_t rmw_lock;
+ struct cpc_register_resource cpc_regs[MAX_CPC_REG_ENT];
+ struct acpi_psd_package domain_info;
+ struct kobject kobj;
+--
+2.43.0
+
--- /dev/null
+From b30d8d7066d913cc96b68d434a654a906d95c5db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jul 2024 01:53:39 +0300
+Subject: ACPI: PMIC: Remove unneeded check in tps68470_pmic_opregion_probe()
+
+From: Aleksandr Mishin <amishin@t-argos.ru>
+
+[ Upstream commit 07442c46abad1d50ac82af5e0f9c5de2732c4592 ]
+
+In tps68470_pmic_opregion_probe() pointer 'dev' is compared to NULL which
+is useless.
+
+Fix this issue by removing unneeded check.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: e13452ac3790 ("ACPI / PMIC: Add TI PMIC TPS68470 operation region driver")
+Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Aleksandr Mishin <amishin@t-argos.ru>
+Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://patch.msgid.link/20240730225339.13165-1-amishin@t-argos.ru
+[ rjw: Subject edit ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/pmic/tps68470_pmic.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/acpi/pmic/tps68470_pmic.c b/drivers/acpi/pmic/tps68470_pmic.c
+index ebd03e4729555..0d1a82eeb4b0b 100644
+--- a/drivers/acpi/pmic/tps68470_pmic.c
++++ b/drivers/acpi/pmic/tps68470_pmic.c
+@@ -376,10 +376,8 @@ static int tps68470_pmic_opregion_probe(struct platform_device *pdev)
+ struct tps68470_pmic_opregion *opregion;
+ acpi_status status;
+
+- if (!dev || !tps68470_regmap) {
+- dev_warn(dev, "dev or regmap is NULL\n");
+- return -EINVAL;
+- }
++ if (!tps68470_regmap)
++ return dev_err_probe(dev, -EINVAL, "regmap is missing\n");
+
+ if (!handle) {
+ dev_warn(dev, "acpi handle is NULL\n");
+--
+2.43.0
+
--- /dev/null
+From af201d5200bfaa1af9eed5c2233d5dcfb9f66d3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Aug 2024 11:56:36 +0200
+Subject: ARM: dts: imx7d-zii-rmu2: fix Ethernet PHY pinctrl property
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 0e49cfe364dea4345551516eb2fe53135a10432b ]
+
+There is no "fsl,phy" property in pin controller pincfg nodes:
+
+ imx7d-zii-rmu2.dtb: pinctrl@302c0000: enet1phyinterruptgrp: 'fsl,pins' is a required property
+ imx7d-zii-rmu2.dtb: pinctrl@302c0000: enet1phyinterruptgrp: 'fsl,phy' does not match any of the regexes: 'pinctrl-[0-9]+'
+
+Fixes: f496e6750083 ("ARM: dts: Add ZII support for ZII i.MX7 RMU2 board")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx7d-zii-rmu2.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/imx7d-zii-rmu2.dts b/arch/arm/boot/dts/imx7d-zii-rmu2.dts
+index 1065941807e83..ce59342e55aae 100644
+--- a/arch/arm/boot/dts/imx7d-zii-rmu2.dts
++++ b/arch/arm/boot/dts/imx7d-zii-rmu2.dts
+@@ -350,7 +350,7 @@ MX7D_PAD_SD3_RESET_B__SD3_RESET_B 0x59
+
+ &iomuxc_lpsr {
+ pinctrl_enet1_phy_interrupt: enet1phyinterruptgrp {
+- fsl,phy = <
++ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO02__GPIO1_IO2 0x08
+ >;
+ };
+--
+2.43.0
+
--- /dev/null
+From 3f2981e728781c025ff2c12564b602def67b2a9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Aug 2024 07:51:36 +0200
+Subject: ARM: dts: microchip: sam9x60: Fix rtc/rtt clocks
+
+From: Alexander Dahl <ada@thorsis.com>
+
+[ Upstream commit d355c895fa4ddd8bec15569eee540baeed7df8c5 ]
+
+The RTC and RTT peripherals use the timing domain slow clock (TD_SLCK),
+sourced from the 32.768 kHz crystal oscillator or slow rc oscillator.
+
+The previously used Monitoring domain slow clock (MD_SLCK) is sourced
+from an internal RC oscillator which is most probably not precise enough
+for real time clock purposes.
+
+Fixes: 1e5f532c2737 ("ARM: dts: at91: sam9x60: add device tree for soc and board")
+Fixes: 5f6b33f46346 ("ARM: dts: sam9x60: add rtt")
+Signed-off-by: Alexander Dahl <ada@thorsis.com>
+Link: https://lore.kernel.org/r/20240821055136.6858-1-ada@thorsis.com
+[claudiu.beznea: removed () around the last commit description paragraph,
+ removed " in front of "timing domain slow clock", described that
+ TD_SLCK can also be sourced from slow rc oscillator]
+Signed-off-by: Claudiu Beznea <claudiu.beznea@tuxon.dev>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/sam9x60.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/sam9x60.dtsi b/arch/arm/boot/dts/sam9x60.dtsi
+index e1e0dec8cc1f2..5e569cf1cccfc 100644
+--- a/arch/arm/boot/dts/sam9x60.dtsi
++++ b/arch/arm/boot/dts/sam9x60.dtsi
+@@ -692,7 +692,7 @@ rtt: rtt@fffffe20 {
+ compatible = "microchip,sam9x60-rtt", "atmel,at91sam9260-rtt";
+ reg = <0xfffffe20 0x20>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+- clocks = <&clk32k 0>;
++ clocks = <&clk32k 1>;
+ };
+
+ pit: timer@fffffe40 {
+@@ -718,7 +718,7 @@ rtc: rtc@fffffea8 {
+ compatible = "microchip,sam9x60-rtc", "atmel,at91sam9x5-rtc";
+ reg = <0xfffffea8 0x100>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+- clocks = <&clk32k 0>;
++ clocks = <&clk32k 1>;
+ };
+
+ watchdog: watchdog@ffffff80 {
+--
+2.43.0
+
--- /dev/null
+From 41b34aed9bcb3392db13432d69bb9be288d5dbf0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Aug 2024 07:49:33 +0200
+Subject: ARM: versatile: fix OF node leak in CPUs prepare
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit f2642d97f2105ed17b2ece0c597450f2ff95d704 ]
+
+Machine code is leaking OF node reference from of_find_matching_node()
+in realview_smp_prepare_cpus().
+
+Fixes: 5420b4b15617 ("ARM: realview: add an DT SMP boot method")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Acked-by: Liviu Dudau <liviu.dudau@arm.com>
+Link: https://lore.kernel.org/20240826054934.10724-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-realview/platsmp-dt.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-realview/platsmp-dt.c b/arch/arm/mach-realview/platsmp-dt.c
+index 5ae783767a5d3..083e6a6f75205 100644
+--- a/arch/arm/mach-realview/platsmp-dt.c
++++ b/arch/arm/mach-realview/platsmp-dt.c
+@@ -66,6 +66,7 @@ static void __init realview_smp_prepare_cpus(unsigned int max_cpus)
+ return;
+ }
+ map = syscon_node_to_regmap(np);
++ of_node_put(np);
+ if (IS_ERR(map)) {
+ pr_err("PLATSMP: No syscon regmap\n");
+ return;
+--
+2.43.0
+
--- /dev/null
+From cb6ccf715f0b63029eefa05b6210166bb7583a40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Jul 2024 13:24:36 +0100
+Subject: arm64: dts: renesas: r9a07g044: Correct GICD and GICR sizes
+
+From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+
+[ Upstream commit 833948fb2b63155847ab691a54800f801555429b ]
+
+The RZ/G2L(C) SoC is equipped with the GIC-600. The GICD is 64KiB +
+64KiB for the MBI alias (in total 128KiB), and the GICR is 128KiB per
+CPU.
+
+Fixes: 68a45525297b2 ("arm64: dts: renesas: Add initial DTSI for RZ/G2{L,LC} SoC's")
+Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Link: https://lore.kernel.org/20240730122436.350013-5-prabhakar.mahadev-lad.rj@bp.renesas.com
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/renesas/r9a07g044.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
+index 5f3bc2898daf2..0818560913028 100644
+--- a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
++++ b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
+@@ -300,8 +300,8 @@ gic: interrupt-controller@11900000 {
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+- reg = <0x0 0x11900000 0 0x40000>,
+- <0x0 0x11940000 0 0x60000>;
++ reg = <0x0 0x11900000 0 0x20000>,
++ <0x0 0x11940000 0 0x40000>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
+ };
+ };
+--
+2.43.0
+
--- /dev/null
+From d9eecb2c0c565d53090118a047a7b868a72edfdc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Sep 2024 11:20:58 +0200
+Subject: bareudp: Pull inner IP header in bareudp_udp_encap_recv().
+
+From: Guillaume Nault <gnault@redhat.com>
+
+[ Upstream commit 45fa29c85117170b0508790f878b13ec6593c888 ]
+
+Bareudp reads the inner IP header to get the ECN value. Therefore, it
+needs to ensure that it's part of the skb's linear data.
+
+This is similar to the vxlan and geneve fixes for that same problem:
+ * commit f7789419137b ("vxlan: Pull inner IP header in vxlan_rcv().")
+ * commit 1ca1ba465e55 ("geneve: make sure to pull inner header in
+ geneve_rx()")
+
+Fixes: 571912c69f0e ("net: UDP tunnel encapsulation module for tunnelling different protocols like MPLS, IP, NSH etc.")
+Signed-off-by: Guillaume Nault <gnault@redhat.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/5205940067c40218a70fbb888080466b2fc288db.1726046181.git.gnault@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bareudp.c | 20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c
+index 43d038a5123e7..3fcd3b84a066e 100644
+--- a/drivers/net/bareudp.c
++++ b/drivers/net/bareudp.c
+@@ -60,6 +60,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
+ __be16 proto;
+ void *oiph;
+ int err;
++ int nh;
+
+ bareudp = rcu_dereference_sk_user_data(sk);
+ if (!bareudp)
+@@ -137,10 +138,25 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
+ }
+ skb_dst_set(skb, &tun_dst->dst);
+ skb->dev = bareudp->dev;
+- oiph = skb_network_header(skb);
+- skb_reset_network_header(skb);
+ skb_reset_mac_header(skb);
+
++ /* Save offset of outer header relative to skb->head,
++ * because we are going to reset the network header to the inner header
++ * and might change skb->head.
++ */
++ nh = skb_network_header(skb) - skb->head;
++
++ skb_reset_network_header(skb);
++
++ if (!pskb_inet_may_pull(skb)) {
++ DEV_STATS_INC(bareudp->dev, rx_length_errors);
++ DEV_STATS_INC(bareudp->dev, rx_errors);
++ goto drop;
++ }
++
++ /* Get the outer header. */
++ oiph = skb->head + nh;
++
+ if (!ipv6_mod_enabled() || family == AF_INET)
+ err = IP_ECN_decapsulate(oiph, skb);
+ else
+--
+2.43.0
+
--- /dev/null
+From 78dd7e884bf8d24f4291d4ff5c5dcb9a3c74f215 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Sep 2024 11:21:05 +0200
+Subject: bareudp: Pull inner IP header on xmit.
+
+From: Guillaume Nault <gnault@redhat.com>
+
+[ Upstream commit c471236b2359e6b27388475dd04fff0a5e2bf922 ]
+
+Both bareudp_xmit_skb() and bareudp6_xmit_skb() read their skb's inner
+IP header to get its ECN value (with ip_tunnel_ecn_encap()). Therefore
+we need to ensure that the inner IP header is part of the skb's linear
+data.
+
+Fixes: 571912c69f0e ("net: UDP tunnel encapsulation module for tunnelling different protocols like MPLS, IP, NSH etc.")
+Signed-off-by: Guillaume Nault <gnault@redhat.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/267328222f0a11519c6de04c640a4f87a38ea9ed.1726046181.git.gnault@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bareudp.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c
+index 3fcd3b84a066e..bec8a2c8656c0 100644
+--- a/drivers/net/bareudp.c
++++ b/drivers/net/bareudp.c
+@@ -312,6 +312,9 @@ static int bareudp_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ __be32 saddr;
+ int err;
+
++ if (!skb_vlan_inet_prepare(skb, skb->protocol != htons(ETH_P_TEB)))
++ return -EINVAL;
++
+ if (!sock)
+ return -ESHUTDOWN;
+
+@@ -375,6 +378,9 @@ static int bareudp6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ __be16 sport;
+ int err;
+
++ if (!skb_vlan_inet_prepare(skb, skb->protocol != htons(ETH_P_TEB)))
++ return -EINVAL;
++
+ if (!sock)
+ return -ESHUTDOWN;
+
+--
+2.43.0
+
--- /dev/null
+From c619abcf0a08289ff99848689a68dcf283391e59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Sep 2024 21:03:27 +0800
+Subject: block, bfq: choose the last bfqq from merge chain in
+ bfq_setup_cooperator()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 0e456dba86c7f9a19792204a044835f1ca2c8dbb ]
+
+Consider the following merge chain:
+
+Process 1 Process 2 Process 3 Process 4
+ (BIC1) (BIC2) (BIC3) (BIC4)
+ Λ | | |
+ \--------------\ \-------------\ \-------------\|
+ V V V
+ bfqq1--------->bfqq2---------->bfqq3----------->bfqq4
+
+IO from Process 1 will get bfqf2 from BIC1 first, then
+bfq_setup_cooperator() will found bfqq2 already merged to bfqq3 and then
+handle this IO from bfqq3. However, the merge chain can be much deeper
+and bfqq3 can be merged to other bfqq as well.
+
+Fix this problem by iterating to the last bfqq in
+bfq_setup_cooperator().
+
+Fixes: 36eca8948323 ("block, bfq: add Early Queue Merge (EQM)")
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20240902130329.3787024-3-yukuai1@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bfq-iosched.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index 4a85bc1a8eeb9..907d8d097810a 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -2753,8 +2753,12 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ struct bfq_queue *in_service_bfqq, *new_bfqq;
+
+ /* if a merge has already been setup, then proceed with that first */
+- if (bfqq->new_bfqq)
+- return bfqq->new_bfqq;
++ new_bfqq = bfqq->new_bfqq;
++ if (new_bfqq) {
++ while (new_bfqq->new_bfqq)
++ new_bfqq = new_bfqq->new_bfqq;
++ return new_bfqq;
++ }
+
+ /*
+ * Check delayed stable merge for rotational or non-queueing
+--
+2.43.0
+
--- /dev/null
+From 606219cf3b9cc56e91d0611a96150ffa86491bf9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Sep 2024 21:03:28 +0800
+Subject: block, bfq: don't break merge chain in bfq_split_bfqq()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 42c306ed723321af4003b2a41bb73728cab54f85 ]
+
+Consider the following scenario:
+
+ Process 1 Process 2 Process 3 Process 4
+ (BIC1) (BIC2) (BIC3) (BIC4)
+ Λ | | |
+ \-------------\ \-------------\ \--------------\|
+ V V V
+ bfqq1--------->bfqq2---------->bfqq3----------->bfqq4
+ref 0 1 2 4
+
+If Process 1 issue a new IO and bfqq2 is found, and then bfq_init_rq()
+decide to spilt bfqq2 by bfq_split_bfqq(). Howerver, procress reference
+of bfqq2 is 1 and bfq_split_bfqq() just clear the coop flag, which will
+break the merge chain.
+
+Expected result: caller will allocate a new bfqq for BIC1
+
+ Process 1 Process 2 Process 3 Process 4
+ (BIC1) (BIC2) (BIC3) (BIC4)
+ | | |
+ \-------------\ \--------------\|
+ V V
+ bfqq1--------->bfqq2---------->bfqq3----------->bfqq4
+ref 0 0 1 3
+
+Since the condition is only used for the last bfqq4 when the previous
+bfqq2 and bfqq3 are already splited. Fix the problem by checking if
+bfqq is the last one in the merge chain as well.
+
+Fixes: 36eca8948323 ("block, bfq: add Early Queue Merge (EQM)")
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20240902130329.3787024-4-yukuai1@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bfq-iosched.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index 907d8d097810a..ab16b4a66c425 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -6474,7 +6474,7 @@ bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq)
+ {
+ bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue");
+
+- if (bfqq_process_refs(bfqq) == 1) {
++ if (bfqq_process_refs(bfqq) == 1 && !bfqq->new_bfqq) {
+ bfqq->pid = current->pid;
+ bfq_clear_bfqq_coop(bfqq);
+ bfq_clear_bfqq_split_coop(bfqq);
+--
+2.43.0
+
--- /dev/null
+From 11576ba44467d9f0bad09ef179a80355bee64cab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Sep 2024 21:03:26 +0800
+Subject: block, bfq: fix possible UAF for bfqq->bic with merge chain
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 18ad4df091dd5d067d2faa8fce1180b79f7041a7 ]
+
+1) initial state, three tasks:
+
+ Process 1 Process 2 Process 3
+ (BIC1) (BIC2) (BIC3)
+ | Λ | Λ | Λ
+ | | | | | |
+ V | V | V |
+ bfqq1 bfqq2 bfqq3
+process ref: 1 1 1
+
+2) bfqq1 merged to bfqq2:
+
+ Process 1 Process 2 Process 3
+ (BIC1) (BIC2) (BIC3)
+ | | | Λ
+ \--------------\| | |
+ V V |
+ bfqq1--------->bfqq2 bfqq3
+process ref: 0 2 1
+
+3) bfqq2 merged to bfqq3:
+
+ Process 1 Process 2 Process 3
+ (BIC1) (BIC2) (BIC3)
+ here -> Λ | |
+ \--------------\ \-------------\|
+ V V
+ bfqq1--------->bfqq2---------->bfqq3
+process ref: 0 1 3
+
+In this case, IO from Process 1 will get bfqq2 from BIC1 first, and then
+get bfqq3 through merge chain, and finially handle IO by bfqq3.
+Howerver, current code will think bfqq2 is owned by BIC1, like initial
+state, and set bfqq2->bic to BIC1.
+
+bfq_insert_request
+-> by Process 1
+ bfqq = bfq_init_rq(rq)
+ bfqq = bfq_get_bfqq_handle_split
+ bfqq = bic_to_bfqq
+ -> get bfqq2 from BIC1
+ bfqq->ref++
+ rq->elv.priv[0] = bic
+ rq->elv.priv[1] = bfqq
+ if (bfqq_process_refs(bfqq) == 1)
+ bfqq->bic = bic
+ -> record BIC1 to bfqq2
+
+ __bfq_insert_request
+ new_bfqq = bfq_setup_cooperator
+ -> get bfqq3 from bfqq2->new_bfqq
+ bfqq_request_freed(bfqq)
+ new_bfqq->ref++
+ rq->elv.priv[1] = new_bfqq
+ -> handle IO by bfqq3
+
+Fix the problem by checking bfqq is from merge chain fist. And this
+might fix a following problem reported by our syzkaller(unreproducible):
+
+==================================================================
+BUG: KASAN: slab-use-after-free in bfq_do_early_stable_merge block/bfq-iosched.c:5692 [inline]
+BUG: KASAN: slab-use-after-free in bfq_do_or_sched_stable_merge block/bfq-iosched.c:5805 [inline]
+BUG: KASAN: slab-use-after-free in bfq_get_queue+0x25b0/0x2610 block/bfq-iosched.c:5889
+Write of size 1 at addr ffff888123839eb8 by task kworker/0:1H/18595
+
+CPU: 0 PID: 18595 Comm: kworker/0:1H Tainted: G L 6.6.0-07439-gba2303cacfda #6
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
+Workqueue: kblockd blk_mq_requeue_work
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0x91/0xf0 lib/dump_stack.c:106
+ print_address_description mm/kasan/report.c:364 [inline]
+ print_report+0x10d/0x610 mm/kasan/report.c:475
+ kasan_report+0x8e/0xc0 mm/kasan/report.c:588
+ bfq_do_early_stable_merge block/bfq-iosched.c:5692 [inline]
+ bfq_do_or_sched_stable_merge block/bfq-iosched.c:5805 [inline]
+ bfq_get_queue+0x25b0/0x2610 block/bfq-iosched.c:5889
+ bfq_get_bfqq_handle_split+0x169/0x5d0 block/bfq-iosched.c:6757
+ bfq_init_rq block/bfq-iosched.c:6876 [inline]
+ bfq_insert_request block/bfq-iosched.c:6254 [inline]
+ bfq_insert_requests+0x1112/0x5cf0 block/bfq-iosched.c:6304
+ blk_mq_insert_request+0x290/0x8d0 block/blk-mq.c:2593
+ blk_mq_requeue_work+0x6bc/0xa70 block/blk-mq.c:1502
+ process_one_work kernel/workqueue.c:2627 [inline]
+ process_scheduled_works+0x432/0x13f0 kernel/workqueue.c:2700
+ worker_thread+0x6f2/0x1160 kernel/workqueue.c:2781
+ kthread+0x33c/0x440 kernel/kthread.c:388
+ ret_from_fork+0x4d/0x80 arch/x86/kernel/process.c:147
+ ret_from_fork_asm+0x1b/0x30 arch/x86/entry/entry_64.S:305
+ </TASK>
+
+Allocated by task 20776:
+ kasan_save_stack+0x20/0x40 mm/kasan/common.c:45
+ kasan_set_track+0x25/0x30 mm/kasan/common.c:52
+ __kasan_slab_alloc+0x87/0x90 mm/kasan/common.c:328
+ kasan_slab_alloc include/linux/kasan.h:188 [inline]
+ slab_post_alloc_hook mm/slab.h:763 [inline]
+ slab_alloc_node mm/slub.c:3458 [inline]
+ kmem_cache_alloc_node+0x1a4/0x6f0 mm/slub.c:3503
+ ioc_create_icq block/blk-ioc.c:370 [inline]
+ ioc_find_get_icq+0x180/0xaa0 block/blk-ioc.c:436
+ bfq_prepare_request+0x39/0xf0 block/bfq-iosched.c:6812
+ blk_mq_rq_ctx_init.isra.7+0x6ac/0xa00 block/blk-mq.c:403
+ __blk_mq_alloc_requests+0xcc0/0x1070 block/blk-mq.c:517
+ blk_mq_get_new_requests block/blk-mq.c:2940 [inline]
+ blk_mq_submit_bio+0x624/0x27c0 block/blk-mq.c:3042
+ __submit_bio+0x331/0x6f0 block/blk-core.c:624
+ __submit_bio_noacct_mq block/blk-core.c:703 [inline]
+ submit_bio_noacct_nocheck+0x816/0xb40 block/blk-core.c:732
+ submit_bio_noacct+0x7a6/0x1b50 block/blk-core.c:826
+ xlog_write_iclog+0x7d5/0xa00 fs/xfs/xfs_log.c:1958
+ xlog_state_release_iclog+0x3b8/0x720 fs/xfs/xfs_log.c:619
+ xlog_cil_push_work+0x19c5/0x2270 fs/xfs/xfs_log_cil.c:1330
+ process_one_work kernel/workqueue.c:2627 [inline]
+ process_scheduled_works+0x432/0x13f0 kernel/workqueue.c:2700
+ worker_thread+0x6f2/0x1160 kernel/workqueue.c:2781
+ kthread+0x33c/0x440 kernel/kthread.c:388
+ ret_from_fork+0x4d/0x80 arch/x86/kernel/process.c:147
+ ret_from_fork_asm+0x1b/0x30 arch/x86/entry/entry_64.S:305
+
+Freed by task 946:
+ kasan_save_stack+0x20/0x40 mm/kasan/common.c:45
+ kasan_set_track+0x25/0x30 mm/kasan/common.c:52
+ kasan_save_free_info+0x2b/0x50 mm/kasan/generic.c:522
+ ____kasan_slab_free mm/kasan/common.c:236 [inline]
+ __kasan_slab_free+0x12c/0x1c0 mm/kasan/common.c:244
+ kasan_slab_free include/linux/kasan.h:164 [inline]
+ slab_free_hook mm/slub.c:1815 [inline]
+ slab_free_freelist_hook mm/slub.c:1841 [inline]
+ slab_free mm/slub.c:3786 [inline]
+ kmem_cache_free+0x118/0x6f0 mm/slub.c:3808
+ rcu_do_batch+0x35c/0xe30 kernel/rcu/tree.c:2189
+ rcu_core+0x819/0xd90 kernel/rcu/tree.c:2462
+ __do_softirq+0x1b0/0x7a2 kernel/softirq.c:553
+
+Last potentially related work creation:
+ kasan_save_stack+0x20/0x40 mm/kasan/common.c:45
+ __kasan_record_aux_stack+0xaf/0xc0 mm/kasan/generic.c:492
+ __call_rcu_common kernel/rcu/tree.c:2712 [inline]
+ call_rcu+0xce/0x1020 kernel/rcu/tree.c:2826
+ ioc_destroy_icq+0x54c/0x830 block/blk-ioc.c:105
+ ioc_release_fn+0xf0/0x360 block/blk-ioc.c:124
+ process_one_work kernel/workqueue.c:2627 [inline]
+ process_scheduled_works+0x432/0x13f0 kernel/workqueue.c:2700
+ worker_thread+0x6f2/0x1160 kernel/workqueue.c:2781
+ kthread+0x33c/0x440 kernel/kthread.c:388
+ ret_from_fork+0x4d/0x80 arch/x86/kernel/process.c:147
+ ret_from_fork_asm+0x1b/0x30 arch/x86/entry/entry_64.S:305
+
+Second to last potentially related work creation:
+ kasan_save_stack+0x20/0x40 mm/kasan/common.c:45
+ __kasan_record_aux_stack+0xaf/0xc0 mm/kasan/generic.c:492
+ __call_rcu_common kernel/rcu/tree.c:2712 [inline]
+ call_rcu+0xce/0x1020 kernel/rcu/tree.c:2826
+ ioc_destroy_icq+0x54c/0x830 block/blk-ioc.c:105
+ ioc_release_fn+0xf0/0x360 block/blk-ioc.c:124
+ process_one_work kernel/workqueue.c:2627 [inline]
+ process_scheduled_works+0x432/0x13f0 kernel/workqueue.c:2700
+ worker_thread+0x6f2/0x1160 kernel/workqueue.c:2781
+ kthread+0x33c/0x440 kernel/kthread.c:388
+ ret_from_fork+0x4d/0x80 arch/x86/kernel/process.c:147
+ ret_from_fork_asm+0x1b/0x30 arch/x86/entry/entry_64.S:305
+
+The buggy address belongs to the object at ffff888123839d68
+ which belongs to the cache bfq_io_cq of size 1360
+The buggy address is located 336 bytes inside of
+ freed 1360-byte region [ffff888123839d68, ffff88812383a2b8)
+
+The buggy address belongs to the physical page:
+page:ffffea00048e0e00 refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff88812383f588 pfn:0x123838
+head:ffffea00048e0e00 order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0
+flags: 0x17ffffc0000a40(workingset|slab|head|node=0|zone=2|lastcpupid=0x1fffff)
+page_type: 0xffffffff()
+raw: 0017ffffc0000a40 ffff88810588c200 ffffea00048ffa10 ffff888105889488
+raw: ffff88812383f588 0000000000150006 00000001ffffffff 0000000000000000
+page dumped because: kasan: bad access detected
+
+Memory state around the buggy address:
+ ffff888123839d80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ffff888123839e00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+>ffff888123839e80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ^
+ ffff888123839f00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+ ffff888123839f80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+==================================================================
+
+Fixes: 36eca8948323 ("block, bfq: add Early Queue Merge (EQM)")
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20240902130329.3787024-2-yukuai1@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bfq-iosched.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index f54554906451e..4a85bc1a8eeb9 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -6675,7 +6675,8 @@ static struct bfq_queue *bfq_init_rq(struct request *rq)
+ * addition, if the queue has also just been split, we have to
+ * resume its state.
+ */
+- if (likely(bfqq != &bfqd->oom_bfqq) && bfqq_process_refs(bfqq) == 1) {
++ if (likely(bfqq != &bfqd->oom_bfqq) && !bfqq->new_bfqq &&
++ bfqq_process_refs(bfqq) == 1) {
+ bfqq->bic = bic;
+ if (split) {
+ /*
+--
+2.43.0
+
--- /dev/null
+From bdc6aec76731e1723cee7ae41b2968d02e79374e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Sep 2024 18:59:54 +0530
+Subject: block: fix potential invalid pointer dereference in blk_add_partition
+
+From: Riyan Dhiman <riyandhiman14@gmail.com>
+
+[ Upstream commit 26e197b7f9240a4ac301dd0ad520c0c697c2ea7d ]
+
+The blk_add_partition() function initially used a single if-condition
+(IS_ERR(part)) to check for errors when adding a partition. This was
+modified to handle the specific case of -ENXIO separately, allowing the
+function to proceed without logging the error in this case. However,
+this change unintentionally left a path where md_autodetect_dev()
+could be called without confirming that part is a valid pointer.
+
+This commit separates the error handling logic by splitting the
+initial if-condition, improving code readability and handling specific
+error scenarios explicitly. The function now distinguishes the general
+error case from -ENXIO without altering the existing behavior of
+md_autodetect_dev() calls.
+
+Fixes: b72053072c0b (block: allow partitions on host aware zone devices)
+Signed-off-by: Riyan Dhiman <riyandhiman14@gmail.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20240911132954.5874-1-riyandhiman14@gmail.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/partitions/core.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/block/partitions/core.c b/block/partitions/core.c
+index 00fb271a60510..0d1fe2b42b855 100644
+--- a/block/partitions/core.c
++++ b/block/partitions/core.c
+@@ -590,9 +590,11 @@ static bool blk_add_partition(struct gendisk *disk,
+
+ part = add_partition(disk, p, from, size, state->parts[p].flags,
+ &state->parts[p].info);
+- if (IS_ERR(part) && PTR_ERR(part) != -ENXIO) {
+- printk(KERN_ERR " %s: p%d could not be added: %pe\n",
+- disk->disk_name, p, part);
++ if (IS_ERR(part)) {
++ if (PTR_ERR(part) != -ENXIO) {
++ printk(KERN_ERR " %s: p%d could not be added: %pe\n",
++ disk->disk_name, p, part);
++ }
+ return true;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 0bbcf8f49e52180eaa4420fa999ab50735d58140 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jan 2024 00:15:18 +0100
+Subject: block: print symbolic error name instead of error code
+
+From: Christian Heusel <christian@heusel.eu>
+
+[ Upstream commit 25c1772a0493463408489b1fae65cf77fe46cac1 ]
+
+Utilize the %pe print specifier to get the symbolic error name as a
+string (i.e "-ENOMEM") in the log message instead of the error code to
+increase its readablility.
+
+This change was suggested in
+https://lore.kernel.org/all/92972476-0b1f-4d0a-9951-af3fc8bc6e65@suswa.mountain/
+
+Signed-off-by: Christian Heusel <christian@heusel.eu>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Link: https://lore.kernel.org/r/20240111231521.1596838-1-christian@heusel.eu
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Stable-dep-of: 26e197b7f924 ("block: fix potential invalid pointer dereference in blk_add_partition")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/partitions/core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/block/partitions/core.c b/block/partitions/core.c
+index b6a941889bb48..00fb271a60510 100644
+--- a/block/partitions/core.c
++++ b/block/partitions/core.c
+@@ -591,8 +591,8 @@ static bool blk_add_partition(struct gendisk *disk,
+ part = add_partition(disk, p, from, size, state->parts[p].flags,
+ &state->parts[p].info);
+ if (IS_ERR(part) && PTR_ERR(part) != -ENXIO) {
+- printk(KERN_ERR " %s: p%d could not be added: %ld\n",
+- disk->disk_name, p, -PTR_ERR(part));
++ printk(KERN_ERR " %s: p%d could not be added: %pe\n",
++ disk->disk_name, p, part);
+ return true;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 15d3bcdf73b3884bf899e45fbcaad5b60b325256 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Sep 2024 16:51:52 -0400
+Subject: Bluetooth: btusb: Fix not handling ZPL/short-transfer
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 7b05933340f4490ef5b09e84d644d12484b05fdf ]
+
+Requesting transfers of the exact same size of wMaxPacketSize may result
+in ZPL/short-transfer since the USB stack cannot handle it as we are
+limiting the buffer size to be the same as wMaxPacketSize.
+
+Also, in terms of throughput this change has the same effect to
+interrupt endpoint as 290ba200815f "Bluetooth: Improve USB driver throughput
+by increasing the frame size" had for the bulk endpoint, so users of the
+advertisement bearer (e.g. BT Mesh) may benefit from this change.
+
+Fixes: 5e23b923da03 ("[Bluetooth] Add generic driver for Bluetooth USB devices")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Tested-by: Kiran K <kiran.k@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index e45bfe8463a42..fcd1910825b65 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -1002,7 +1002,10 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
+ if (!urb)
+ return -ENOMEM;
+
+- size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
++ /* Use maximum HCI Event size so the USB stack handles
++ * ZPL/short-transfer automatically.
++ */
++ size = HCI_MAX_EVENT_SIZE;
+
+ buf = kmalloc(size, mem_flags);
+ if (!buf) {
+--
+2.43.0
+
--- /dev/null
+From 475db58562072e281312c88c356016564ded5a8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Sep 2024 14:06:02 +0000
+Subject: bonding: Fix unnecessary warnings and logs from
+ bond_xdp_get_xmit_slave()
+
+From: Jiwon Kim <jiwonaid0@gmail.com>
+
+[ Upstream commit 0cbfd45fbcf0cb26d85c981b91c62fe73cdee01c ]
+
+syzbot reported a WARNING in bond_xdp_get_xmit_slave. To reproduce
+this[1], one bond device (bond1) has xdpdrv, which increases
+bpf_master_redirect_enabled_key. Another bond device (bond0) which is
+unsupported by XDP but its slave (veth3) has xdpgeneric that returns
+XDP_TX. This triggers WARN_ON_ONCE() from the xdp_master_redirect().
+To reduce unnecessary warnings and improve log management, we need to
+delete the WARN_ON_ONCE() and add ratelimit to the netdev_err().
+
+[1] Steps to reproduce:
+ # Needs tx_xdp with return XDP_TX;
+ ip l add veth0 type veth peer veth1
+ ip l add veth3 type veth peer veth4
+ ip l add bond0 type bond mode 6 # BOND_MODE_ALB, unsupported by XDP
+ ip l add bond1 type bond # BOND_MODE_ROUNDROBIN by default
+ ip l set veth0 master bond1
+ ip l set bond1 up
+ # Increases bpf_master_redirect_enabled_key
+ ip l set dev bond1 xdpdrv object tx_xdp.o section xdp_tx
+ ip l set veth3 master bond0
+ ip l set bond0 up
+ ip l set veth4 up
+ # Triggers WARN_ON_ONCE() from the xdp_master_redirect()
+ ip l set veth3 xdpgeneric object tx_xdp.o section xdp_tx
+
+Reported-by: syzbot+c187823a52ed505b2257@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=c187823a52ed505b2257
+Fixes: 9e2ee5c7e7c3 ("net, bonding: Add XDP support to the bonding driver")
+Signed-off-by: Jiwon Kim <jiwonaid0@gmail.com>
+Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>
+Link: https://patch.msgid.link/20240918140602.18644-1-jiwonaid0@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index fd0667e1d10ab..67d153cc6a6c0 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -5191,9 +5191,9 @@ bond_xdp_get_xmit_slave(struct net_device *bond_dev, struct xdp_buff *xdp)
+ break;
+
+ default:
+- /* Should never happen. Mode guarded by bond_xdp_check() */
+- netdev_err(bond_dev, "Unknown bonding mode %d for xdp xmit\n", BOND_MODE(bond));
+- WARN_ON_ONCE(1);
++ if (net_ratelimit())
++ netdev_err(bond_dev, "Unknown bonding mode %d for xdp xmit\n",
++ BOND_MODE(bond));
+ return NULL;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From c1896fdd09fb46a33b801a170ef3367eabd54c8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Sep 2024 21:17:46 +0200
+Subject: bpf: Fix bpf_strtol and bpf_strtoul helpers for 32bit
+
+From: Daniel Borkmann <daniel@iogearbox.net>
+
+[ Upstream commit cfe69c50b05510b24e26ccb427c7cc70beafd6c1 ]
+
+The bpf_strtol() and bpf_strtoul() helpers are currently broken on 32bit:
+
+The argument type ARG_PTR_TO_LONG is BPF-side "long", not kernel-side "long"
+and therefore always considered fixed 64bit no matter if 64 or 32bit underlying
+architecture.
+
+This contract breaks in case of the two mentioned helpers since their BPF_CALL
+definition for the helpers was added with {unsigned,}long *res. Meaning, the
+transition from BPF-side "long" (BPF program) to kernel-side "long" (BPF helper)
+breaks here.
+
+Both helpers call __bpf_strtoll() with "long long" correctly, but later assigning
+the result into 32-bit "*(long *)" on 32bit architectures. From a BPF program
+point of view, this means upper bits will be seen as uninitialised.
+
+Therefore, fix both BPF_CALL signatures to {s,u}64 types to fix this situation.
+
+Now, changing also uapi/bpf.h helper documentation which generates bpf_helper_defs.h
+for BPF programs is tricky: Changing signatures there to __{s,u}64 would trigger
+compiler warnings (incompatible pointer types passing 'long *' to parameter of type
+'__s64 *' (aka 'long long *')) for existing BPF programs.
+
+Leaving the signatures as-is would be fine as from BPF program point of view it is
+still BPF-side "long" and thus equivalent to __{s,u}64 on 64 or 32bit underlying
+architectures.
+
+Note that bpf_strtol() and bpf_strtoul() are the only helpers with this issue.
+
+Fixes: d7a4cb9b6705 ("bpf: Introduce bpf_strtol and bpf_strtoul helpers")
+Reported-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/481fcec8-c12c-9abb-8ecb-76c71c009959@iogearbox.net
+Link: https://lore.kernel.org/r/20240913191754.13290-1-daniel@iogearbox.net
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/helpers.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
+index 273f2f0deb239..13f870e47ab6d 100644
+--- a/kernel/bpf/helpers.c
++++ b/kernel/bpf/helpers.c
+@@ -512,7 +512,7 @@ static int __bpf_strtoll(const char *buf, size_t buf_len, u64 flags,
+ }
+
+ BPF_CALL_4(bpf_strtol, const char *, buf, size_t, buf_len, u64, flags,
+- long *, res)
++ s64 *, res)
+ {
+ long long _res;
+ int err;
+@@ -537,7 +537,7 @@ const struct bpf_func_proto bpf_strtol_proto = {
+ };
+
+ BPF_CALL_4(bpf_strtoul, const char *, buf, size_t, buf_len, u64, flags,
+- unsigned long *, res)
++ u64 *, res)
+ {
+ unsigned long long _res;
+ bool is_negative;
+--
+2.43.0
+
--- /dev/null
+From 39821b75d0811f5ea4b2b1f89f6e508735a34c78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Sep 2024 18:22:37 -0700
+Subject: can: bcm: Clear bo->bcm_proc_read after remove_proc_entry().
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 94b0818fa63555a65f6ba107080659ea6bcca63e ]
+
+syzbot reported a warning in bcm_release(). [0]
+
+The blamed change fixed another warning that is triggered when
+connect() is issued again for a socket whose connect()ed device has
+been unregistered.
+
+However, if the socket is just close()d without the 2nd connect(), the
+remaining bo->bcm_proc_read triggers unnecessary remove_proc_entry()
+in bcm_release().
+
+Let's clear bo->bcm_proc_read after remove_proc_entry() in bcm_notify().
+
+[0]
+name '4986'
+WARNING: CPU: 0 PID: 5234 at fs/proc/generic.c:711 remove_proc_entry+0x2e7/0x5d0 fs/proc/generic.c:711
+Modules linked in:
+CPU: 0 UID: 0 PID: 5234 Comm: syz-executor606 Not tainted 6.11.0-rc5-syzkaller-00178-g5517ae241919 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/06/2024
+RIP: 0010:remove_proc_entry+0x2e7/0x5d0 fs/proc/generic.c:711
+Code: ff eb 05 e8 cb 1e 5e ff 48 8b 5c 24 10 48 c7 c7 e0 f7 aa 8e e8 2a 38 8e 09 90 48 c7 c7 60 3a 1b 8c 48 89 de e8 da 42 20 ff 90 <0f> 0b 90 90 48 8b 44 24 18 48 c7 44 24 40 0e 36 e0 45 49 c7 04 07
+RSP: 0018:ffffc9000345fa20 EFLAGS: 00010246
+RAX: 2a2d0aee2eb64600 RBX: ffff888032f1f548 RCX: ffff888029431e00
+RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
+RBP: ffffc9000345fb08 R08: ffffffff8155b2f2 R09: 1ffff1101710519a
+R10: dffffc0000000000 R11: ffffed101710519b R12: ffff888011d38640
+R13: 0000000000000004 R14: 0000000000000000 R15: dffffc0000000000
+FS: 0000000000000000(0000) GS:ffff8880b8800000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007fcfb52722f0 CR3: 000000000e734000 CR4: 00000000003506f0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ <TASK>
+ bcm_release+0x250/0x880 net/can/bcm.c:1578
+ __sock_release net/socket.c:659 [inline]
+ sock_close+0xbc/0x240 net/socket.c:1421
+ __fput+0x24a/0x8a0 fs/file_table.c:422
+ task_work_run+0x24f/0x310 kernel/task_work.c:228
+ exit_task_work include/linux/task_work.h:40 [inline]
+ do_exit+0xa2f/0x27f0 kernel/exit.c:882
+ do_group_exit+0x207/0x2c0 kernel/exit.c:1031
+ __do_sys_exit_group kernel/exit.c:1042 [inline]
+ __se_sys_exit_group kernel/exit.c:1040 [inline]
+ __x64_sys_exit_group+0x3f/0x40 kernel/exit.c:1040
+ x64_sys_call+0x2634/0x2640 arch/x86/include/generated/asm/syscalls_64.h:232
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7fcfb51ee969
+Code: Unable to access opcode bytes at 0x7fcfb51ee93f.
+RSP: 002b:00007ffce0109ca8 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
+RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fcfb51ee969
+RDX: 000000000000003c RSI: 00000000000000e7 RDI: 0000000000000001
+RBP: 00007fcfb526f3b0 R08: ffffffffffffffb8 R09: 0000555500000000
+R10: 0000555500000000 R11: 0000000000000246 R12: 00007fcfb526f3b0
+R13: 0000000000000000 R14: 00007fcfb5271ee0 R15: 00007fcfb51bf160
+ </TASK>
+
+Fixes: 76fe372ccb81 ("can: bcm: Remove proc entry when dev is unregistered.")
+Reported-by: syzbot+0532ac7a06fb1a03187e@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=0532ac7a06fb1a03187e
+Tested-by: syzbot+0532ac7a06fb1a03187e@syzkaller.appspotmail.com
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Link: https://patch.msgid.link/20240905012237.79683-1-kuniyu@amazon.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/bcm.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/can/bcm.c b/net/can/bcm.c
+index 8c039638b196b..5a8bcfe9e3f02 100644
+--- a/net/can/bcm.c
++++ b/net/can/bcm.c
+@@ -1424,8 +1424,10 @@ static void bcm_notify(struct bcm_sock *bo, unsigned long msg,
+ /* remove device reference, if this is our bound device */
+ if (bo->bound && bo->ifindex == dev->ifindex) {
+ #if IS_ENABLED(CONFIG_PROC_FS)
+- if (sock_net(sk)->can.bcmproc_dir && bo->bcm_proc_read)
++ if (sock_net(sk)->can.bcmproc_dir && bo->bcm_proc_read) {
+ remove_proc_entry(bo->procname, sock_net(sk)->can.bcmproc_dir);
++ bo->bcm_proc_read = NULL;
++ }
+ #endif
+ bo->bound = 0;
+ bo->ifindex = 0;
+--
+2.43.0
+
--- /dev/null
+From a29bee7718bba9910a9b1649d0da4098bf75f8d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Aug 2024 20:48:23 +0800
+Subject: can: j1939: use correct function name in comment
+
+From: Zhang Changzhong <zhangchangzhong@huawei.com>
+
+[ Upstream commit dc2ddcd136fe9b6196a7dd01f75f824beb02d43f ]
+
+The function j1939_cancel_all_active_sessions() was renamed to
+j1939_cancel_active_session() but name in comment wasn't updated.
+
+Signed-off-by: Zhang Changzhong <zhangchangzhong@huawei.com>
+Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol")
+Link: https://patch.msgid.link/1724935703-44621-1-git-send-email-zhangchangzhong@huawei.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/j1939/transport.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
+index 25e7339834670..5d2097e5ca3a8 100644
+--- a/net/can/j1939/transport.c
++++ b/net/can/j1939/transport.c
+@@ -1179,10 +1179,10 @@ static enum hrtimer_restart j1939_tp_txtimer(struct hrtimer *hrtimer)
+ break;
+ case -ENETDOWN:
+ /* In this case we should get a netdev_event(), all active
+- * sessions will be cleared by
+- * j1939_cancel_all_active_sessions(). So handle this as an
+- * error, but let j1939_cancel_all_active_sessions() do the
+- * cleanup including propagation of the error to user space.
++ * sessions will be cleared by j1939_cancel_active_session().
++ * So handle this as an error, but let
++ * j1939_cancel_active_session() do the cleanup including
++ * propagation of the error to user space.
+ */
+ break;
+ case -EOVERFLOW:
+--
+2.43.0
+
--- /dev/null
+From 3bc9de992c9443d78f8889ffe8ff59a613c79cc3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Sep 2024 15:07:41 +0200
+Subject: can: m_can: m_can_close(): stop clocks after device has been shut
+ down
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 2c09b50efcad985cf920ca88baa9aa52b1999dcc ]
+
+After calling m_can_stop() an interrupt may be pending or NAPI might
+still be executed. This means the driver might still touch registers
+of the IP core after the clocks have been disabled. This is not good
+practice and might lead to aborts depending on the SoC integration.
+
+To avoid these potential problems, make m_can_close() symmetric to
+m_can_open(), i.e. stop the clocks at the end, right before shutting
+down the transceiver.
+
+Fixes: e0d1f4816f2a ("can: m_can: add Bosch M_CAN controller support")
+Link: https://patch.msgid.link/20240910-can-m_can-fix-ifup-v3-2-6c1720ba45ce@pengutronix.de
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/m_can/m_can.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
+index 07f61ee76ca60..a87f6ce86cea3 100644
+--- a/drivers/net/can/m_can/m_can.c
++++ b/drivers/net/can/m_can/m_can.c
+@@ -1583,7 +1583,6 @@ static int m_can_close(struct net_device *dev)
+ napi_disable(&cdev->napi);
+
+ m_can_stop(dev);
+- m_can_clk_stop(cdev);
+ free_irq(dev->irq, dev);
+
+ if (cdev->is_peripheral) {
+@@ -1598,6 +1597,7 @@ static int m_can_close(struct net_device *dev)
+ close_candev(dev);
+ can_led_event(dev, CAN_LED_EVENT_STOP);
+
++ m_can_clk_stop(cdev);
+ phy_power_off(cdev->transceiver);
+
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From ed6f985c31a2515cd7d3341e4f5de4474a30296a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jun 2024 21:33:38 +0800
+Subject: clk: imx: imx8mp: fix clock tree update of TF-A managed clocks
+
+From: Zhipeng Wang <zhipeng.wang_1@nxp.com>
+
+[ Upstream commit 3d29036853b9cb07ac49e8261fca82a940be5c41 ]
+
+On the i.MX8M*, the TF-A exposes a SiP (Silicon Provider) service
+for DDR frequency scaling. The imx8m-ddrc-devfreq driver calls the
+SiP and then does clk_set_parent on the DDR muxes to synchronize
+the clock tree.
+
+since commit 936c383673b9 ("clk: imx: fix composite peripheral flags"),
+these TF-A managed muxes have SET_PARENT_GATE set, which results
+in imx8m-ddrc-devfreq's clk_set_parent after SiP failing with -EBUSY:
+
+clk_set_parent(dram_apb_src, sys1_pll_40m);(busfreq-imx8mq.c)
+
+commit 926bf91248dd
+("clk: imx8m: fix clock tree update of TF-A managed clocks") adds this
+method and enables 8mm, 8mn and 8mq. i.MX8MP also needs it.
+
+This is safe to do, because updating the Linux clock tree to reflect
+reality will always be glitch-free.
+
+Another reason to this patch is that powersave image BT music
+requires dram to be 400MTS, so clk_set_parent(dram_alt_src,
+sys1_pll_800m); is required. Without this patch, it will not succeed.
+
+Fixes: 936c383673b9 ("clk: imx: fix composite peripheral flags")
+Signed-off-by: Zhipeng Wang <zhipeng.wang_1@nxp.com>
+Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20240607133347.3291040-7-peng.fan@oss.nxp.com
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx8mp.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
+index cdeacdc143b5c..8e980271b9dc6 100644
+--- a/drivers/clk/imx/clk-imx8mp.c
++++ b/drivers/clk/imx/clk-imx8mp.c
+@@ -566,8 +566,8 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
+
+ hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1);
+
+- hws[IMX8MP_CLK_DRAM_ALT] = imx8m_clk_hw_composite("dram_alt", imx8mp_dram_alt_sels, ccm_base + 0xa000);
+- hws[IMX8MP_CLK_DRAM_APB] = imx8m_clk_hw_composite_critical("dram_apb", imx8mp_dram_apb_sels, ccm_base + 0xa080);
++ hws[IMX8MP_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mp_dram_alt_sels, ccm_base + 0xa000);
++ hws[IMX8MP_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mp_dram_apb_sels, ccm_base + 0xa080);
+ hws[IMX8MP_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mp_vpu_g1_sels, ccm_base + 0xa100);
+ hws[IMX8MP_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mp_vpu_g2_sels, ccm_base + 0xa180);
+ hws[IMX8MP_CLK_CAN1] = imx8m_clk_hw_composite("can1", imx8mp_can1_sels, ccm_base + 0xa200);
+--
+2.43.0
+
--- /dev/null
+From 98e7a5e3d841e4f6ac84c464e76a71e02c368e61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jun 2024 21:33:46 +0800
+Subject: clk: imx: imx8qxp: Parent should be initialized earlier than the
+ clock
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit 766c386c16c9899461b83573a06380d364c6e261 ]
+
+The initialization order of SCU clocks affects the sequence of SCU clock
+resume. If there are no other effects, the earlier the initialization,
+the earlier the resume. During SCU clock resume, the clock rate is
+restored. As SCFW guidelines, configure the parent clock rate before
+configuring the child rate.
+
+Fixes: babfaa9556d7 ("clk: imx: scu: add more scu clocks")
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20240607133347.3291040-15-peng.fan@oss.nxp.com
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx8qxp.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c
+index 43d59bc5a229a..6d41ae4ebf726 100644
+--- a/drivers/clk/imx/clk-imx8qxp.c
++++ b/drivers/clk/imx/clk-imx8qxp.c
+@@ -166,8 +166,8 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
+ imx_clk_scu("pwm_clk", IMX_SC_R_LCD_0_PWM_0, IMX_SC_PM_CLK_PER);
+ imx_clk_scu("elcdif_pll", IMX_SC_R_ELCDIF_PLL, IMX_SC_PM_CLK_PLL);
+ imx_clk_scu2("lcd_clk", lcd_sels, ARRAY_SIZE(lcd_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_PER);
+- imx_clk_scu2("lcd_pxl_clk", lcd_pxl_sels, ARRAY_SIZE(lcd_pxl_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_MISC0);
+ imx_clk_scu("lcd_pxl_bypass_div_clk", IMX_SC_R_LCD_0, IMX_SC_PM_CLK_BYPASS);
++ imx_clk_scu2("lcd_pxl_clk", lcd_pxl_sels, ARRAY_SIZE(lcd_pxl_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_MISC0);
+
+ /* Audio SS */
+ imx_clk_scu("audio_pll0_clk", IMX_SC_R_AUDIO_PLL_0, IMX_SC_PM_CLK_PLL);
+@@ -207,11 +207,11 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
+ imx_clk_scu2("dc0_disp1_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1);
+ imx_clk_scu("dc0_bypass1_clk", IMX_SC_R_DC_0_VIDEO1, IMX_SC_PM_CLK_BYPASS);
+
+- imx_clk_scu2("dc1_disp0_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC0);
+- imx_clk_scu2("dc1_disp1_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC1);
+ imx_clk_scu("dc1_pll0_clk", IMX_SC_R_DC_1_PLL_0, IMX_SC_PM_CLK_PLL);
+ imx_clk_scu("dc1_pll1_clk", IMX_SC_R_DC_1_PLL_1, IMX_SC_PM_CLK_PLL);
+ imx_clk_scu("dc1_bypass0_clk", IMX_SC_R_DC_1_VIDEO0, IMX_SC_PM_CLK_BYPASS);
++ imx_clk_scu2("dc1_disp0_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC0);
++ imx_clk_scu2("dc1_disp1_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC1);
+ imx_clk_scu("dc1_bypass1_clk", IMX_SC_R_DC_1_VIDEO1, IMX_SC_PM_CLK_BYPASS);
+
+ /* MIPI-LVDS SS */
+--
+2.43.0
+
--- /dev/null
+From 8218900a437a050bb545f31126faba2494dbb416 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jun 2024 21:33:45 +0800
+Subject: clk: imx: imx8qxp: Register dc0_bypass0_clk before disp clk
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit e61352d5ecdc0da2e7253121c15d9a3e040f78a1 ]
+
+The initialization order of SCU clocks affects the sequence of SCU clock
+resume. If there are no other effects, the earlier the initialization,
+the earlier the resume. During SCU clock resume, the clock rate is
+restored. As SCFW guidelines, configure the parent clock rate before
+configuring the child rate.
+
+Fixes: 91e916771de0 ("clk: imx: scu: remove legacy scu clock binding support")
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://lore.kernel.org/r/20240607133347.3291040-14-peng.fan@oss.nxp.com
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk-imx8qxp.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c
+index ef560b59df11f..43d59bc5a229a 100644
+--- a/drivers/clk/imx/clk-imx8qxp.c
++++ b/drivers/clk/imx/clk-imx8qxp.c
+@@ -200,11 +200,11 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
+ imx_clk_scu("usb3_lpm_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MISC);
+
+ /* Display controller SS */
+- imx_clk_scu2("dc0_disp0_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0);
+- imx_clk_scu2("dc0_disp1_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1);
+ imx_clk_scu("dc0_pll0_clk", IMX_SC_R_DC_0_PLL_0, IMX_SC_PM_CLK_PLL);
+ imx_clk_scu("dc0_pll1_clk", IMX_SC_R_DC_0_PLL_1, IMX_SC_PM_CLK_PLL);
+ imx_clk_scu("dc0_bypass0_clk", IMX_SC_R_DC_0_VIDEO0, IMX_SC_PM_CLK_BYPASS);
++ imx_clk_scu2("dc0_disp0_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0);
++ imx_clk_scu2("dc0_disp1_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1);
+ imx_clk_scu("dc0_bypass1_clk", IMX_SC_R_DC_0_VIDEO1, IMX_SC_PM_CLK_BYPASS);
+
+ imx_clk_scu2("dc1_disp0_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC0);
+--
+2.43.0
+
--- /dev/null
+From b247a5a02eb73135ccc9465d4c0ba75514f9f21f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Jun 2024 17:03:53 +0000
+Subject: clk: rockchip: Set parent rate for DCLK_VOP clock on RK3228
+
+From: Jonas Karlman <jonas@kwiboo.se>
+
+[ Upstream commit 1d34b9757523c1ad547bd6d040381f62d74a3189 ]
+
+Similar to DCLK_LCDC on RK3328, the DCLK_VOP on RK3228 is typically
+parented by the hdmiphy clk and it is expected that the DCLK_VOP and
+hdmiphy clk rate are kept in sync.
+
+Use CLK_SET_RATE_PARENT and CLK_SET_RATE_NO_REPARENT flags, same as used
+on RK3328, to make full use of all possible supported display modes.
+
+Fixes: 0a9d4ac08ebc ("clk: rockchip: set the clock ids for RK3228 VOP")
+Fixes: 307a2e9ac524 ("clk: rockchip: add clock controller for rk3228")
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Link: https://lore.kernel.org/r/20240615170417.3134517-3-jonas@kwiboo.se
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/rockchip/clk-rk3228.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c
+index a24a35553e134..7343d2d7676bc 100644
+--- a/drivers/clk/rockchip/clk-rk3228.c
++++ b/drivers/clk/rockchip/clk-rk3228.c
+@@ -409,7 +409,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
+ RK2928_CLKSEL_CON(29), 0, 3, DFLAGS),
+ DIV(0, "sclk_vop_pre", "sclk_vop_src", 0,
+ RK2928_CLKSEL_CON(27), 8, 8, DFLAGS),
+- MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, 0,
++ MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+ RK2928_CLKSEL_CON(27), 1, 1, MFLAGS),
+
+ FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
+--
+2.43.0
+
--- /dev/null
+From d59c1670beb53b0e40f1728e5e4c54a372097ed1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Aug 2024 10:35:29 -0500
+Subject: clk: ti: dra7-atl: Fix leak of of_nodes
+
+From: David Lechner <dlechner@baylibre.com>
+
+[ Upstream commit 9d6e9f10e2e031fb7bfb3030a7d1afc561a28fea ]
+
+This fix leaking the of_node references in of_dra7_atl_clk_probe().
+
+The docs for of_parse_phandle_with_args() say that the caller must call
+of_node_put() on the returned node. This adds the missing of_node_put()
+to fix the leak.
+
+Fixes: 9ac33b0ce81f ("CLK: TI: Driver for DRA7 ATL (Audio Tracking Logic)")
+Signed-off-by: David Lechner <dlechner@baylibre.com>
+Link: https://lore.kernel.org/r/20240826-clk-fix-leak-v1-1-f55418a13aa6@baylibre.com
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/ti/clk-dra7-atl.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c
+index 62508e74a47a7..fc266c0ab6293 100644
+--- a/drivers/clk/ti/clk-dra7-atl.c
++++ b/drivers/clk/ti/clk-dra7-atl.c
+@@ -258,6 +258,7 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
+ }
+
+ clk = of_clk_get_from_provider(&clkspec);
++ of_node_put(clkspec.np);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to get atl clock %d from provider\n",
+ __func__, i);
+--
+2.43.0
+
--- /dev/null
+From d6243cffb8cf651eeaf5e90bc0f05b287258dbc2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 Jul 2024 15:27:13 +0530
+Subject: clocksource/drivers/qcom: Add missing iounmap() on errors in
+ msm_dt_timer_init()
+
+From: Ankit Agrawal <agrawal.ag.ankit@gmail.com>
+
+[ Upstream commit ca140a0dc0a18acd4653b56db211fec9b2339986 ]
+
+Add the missing iounmap() when clock frequency fails to get read by the
+of_property_read_u32() call, or if the call to msm_timer_init() fails.
+
+Fixes: 6e3321631ac2 ("ARM: msm: Add DT support to msm_timer")
+Signed-off-by: Ankit Agrawal <agrawal.ag.ankit@gmail.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20240713095713.GA430091@bnew-VirtualBox
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clocksource/timer-qcom.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clocksource/timer-qcom.c b/drivers/clocksource/timer-qcom.c
+index b4afe3a675835..eac4c95c6127f 100644
+--- a/drivers/clocksource/timer-qcom.c
++++ b/drivers/clocksource/timer-qcom.c
+@@ -233,6 +233,7 @@ static int __init msm_dt_timer_init(struct device_node *np)
+ }
+
+ if (of_property_read_u32(np, "clock-frequency", &freq)) {
++ iounmap(cpu0_base);
+ pr_err("Unknown frequency\n");
+ return -EINVAL;
+ }
+@@ -243,7 +244,11 @@ static int __init msm_dt_timer_init(struct device_node *np)
+ freq /= 4;
+ writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
+
+- return msm_timer_init(freq, 32, irq, !!percpu_offset);
++ ret = msm_timer_init(freq, 32, irq, !!percpu_offset);
++ if (ret)
++ iounmap(cpu0_base);
++
++ return ret;
+ }
+ TIMER_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
+ TIMER_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
+--
+2.43.0
+
--- /dev/null
+From cf52bdfe6f3f3d8c23f012283a570f1edb4a7e31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jul 2024 14:28:46 +0100
+Subject: coresight: tmc: sg: Do not leak sg_table
+
+From: Suzuki K Poulose <suzuki.poulose@arm.com>
+
+[ Upstream commit c58dc5a1f886f2fcc1133746d0cbaa1fe7fd44ff ]
+
+Running perf with cs_etm on Juno triggers the following kmemleak warning !
+
+:~# cat /sys/kernel/debug/kmemleak
+ unreferenced object 0xffffff8806b6d720 (size 96):
+ comm "perf", pid 562, jiffies 4297810960
+ hex dump (first 32 bytes):
+ 38 d8 13 07 88 ff ff ff 00 d0 9e 85 c0 ff ff ff 8...............
+ 00 10 00 88 c0 ff ff ff 00 f0 ff f7 ff 00 00 00 ................
+ backtrace (crc 1dbf6e00):
+ [<ffffffc08107381c>] kmemleak_alloc+0xbc/0xd8
+ [<ffffffc0802f9798>] kmalloc_trace_noprof+0x220/0x2e8
+ [<ffffffc07bb71948>] tmc_alloc_sg_table+0x48/0x208 [coresight_tmc]
+ [<ffffffc07bb71cbc>] tmc_etr_alloc_sg_buf+0xac/0x240 [coresight_tmc]
+ [<ffffffc07bb72538>] tmc_alloc_etr_buf.constprop.0+0x1f0/0x260 [coresight_tmc]
+ [<ffffffc07bb7280c>] alloc_etr_buf.constprop.0.isra.0+0x74/0xa8 [coresight_tmc]
+ [<ffffffc07bb72950>] tmc_alloc_etr_buffer+0x110/0x260 [coresight_tmc]
+ [<ffffffc07bb38afc>] etm_setup_aux+0x204/0x3b0 [coresight]
+ [<ffffffc08025837c>] rb_alloc_aux+0x20c/0x318
+ [<ffffffc08024dd84>] perf_mmap+0x2e4/0x7a0
+ [<ffffffc0802cceb0>] mmap_region+0x3b0/0xa08
+ [<ffffffc0802cd8a8>] do_mmap+0x3a0/0x500
+ [<ffffffc080295328>] vm_mmap_pgoff+0x100/0x1d0
+ [<ffffffc0802cadf8>] ksys_mmap_pgoff+0xb8/0x110
+ [<ffffffc080020688>] __arm64_sys_mmap+0x38/0x58
+ [<ffffffc080028fc0>] invoke_syscall.constprop.0+0x58/0x100
+
+This due to the fact that we do not free the "sg_table" itself while
+freeing up the SG table and data pages. Fix this by freeing the sg_table
+in tmc_free_sg_table().
+
+Fixes: 99443ea19e8b ("coresight: Add generic TMC sg table framework")
+Cc: Mike Leach <mike.leach@linaro.org>
+Cc: James Clark <james.clark@arm.com>
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
+Link: https://lore.kernel.org/r/20240702132846.1677261-1-suzuki.poulose@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwtracing/coresight/coresight-tmc-etr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
+index b9cd1f9555523..3b58aed97fc1c 100644
+--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
++++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
+@@ -257,6 +257,7 @@ void tmc_free_sg_table(struct tmc_sg_table *sg_table)
+ {
+ tmc_free_table_pages(sg_table);
+ tmc_free_data_pages(sg_table);
++ kfree(sg_table);
+ }
+ EXPORT_SYMBOL_GPL(tmc_free_sg_table);
+
+@@ -338,7 +339,6 @@ struct tmc_sg_table *tmc_alloc_sg_table(struct device *dev,
+ rc = tmc_alloc_table_pages(sg_table);
+ if (rc) {
+ tmc_free_sg_table(sg_table);
+- kfree(sg_table);
+ return ERR_PTR(rc);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 0743d90e6f5a99cc285123bdbcfb87d53f900b6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Aug 2024 08:19:15 -0500
+Subject: cpufreq: ti-cpufreq: Introduce quirks to handle syscon fails
+ appropriately
+
+From: Nishanth Menon <nm@ti.com>
+
+[ Upstream commit abc00ffda43bd4ba85896713464c7510c39f8165 ]
+
+Commit b4bc9f9e27ed ("cpufreq: ti-cpufreq: add support for omap34xx
+and omap36xx") introduced special handling for OMAP3 class devices
+where syscon node may not be present. However, this also creates a bug
+where the syscon node is present, however the offset used to read
+is beyond the syscon defined range.
+
+Fix this by providing a quirk option that is populated when such
+special handling is required. This allows proper failure for all other
+platforms when the syscon node and efuse offsets are mismatched.
+
+Fixes: b4bc9f9e27ed ("cpufreq: ti-cpufreq: add support for omap34xx and omap36xx")
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Tested-by: Dhruva Gole <d-gole@ti.com>
+Reviewed-by: Kevin Hilman <khilman@baylibre.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/ti-cpufreq.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c
+index 88bffa0bd0139..c91d416fc5809 100644
+--- a/drivers/cpufreq/ti-cpufreq.c
++++ b/drivers/cpufreq/ti-cpufreq.c
+@@ -53,6 +53,9 @@ struct ti_cpufreq_soc_data {
+ unsigned long efuse_shift;
+ unsigned long rev_offset;
+ bool multi_regulator;
++/* Backward compatibility hack: Might have missing syscon */
++#define TI_QUIRK_SYSCON_MAY_BE_MISSING 0x1
++ u8 quirks;
+ };
+
+ struct ti_cpufreq_data {
+@@ -156,6 +159,7 @@ static struct ti_cpufreq_soc_data omap34xx_soc_data = {
+ .efuse_mask = BIT(3),
+ .rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE,
+ .multi_regulator = false,
++ .quirks = TI_QUIRK_SYSCON_MAY_BE_MISSING,
+ };
+
+ /*
+@@ -183,6 +187,7 @@ static struct ti_cpufreq_soc_data omap36xx_soc_data = {
+ .efuse_mask = BIT(9),
+ .rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE,
+ .multi_regulator = true,
++ .quirks = TI_QUIRK_SYSCON_MAY_BE_MISSING,
+ };
+
+ /*
+@@ -197,6 +202,7 @@ static struct ti_cpufreq_soc_data am3517_soc_data = {
+ .efuse_mask = 0,
+ .rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE,
+ .multi_regulator = false,
++ .quirks = TI_QUIRK_SYSCON_MAY_BE_MISSING,
+ };
+
+
+@@ -216,7 +222,7 @@ static int ti_cpufreq_get_efuse(struct ti_cpufreq_data *opp_data,
+
+ ret = regmap_read(opp_data->syscon, opp_data->soc_data->efuse_offset,
+ &efuse);
+- if (ret == -EIO) {
++ if (opp_data->soc_data->quirks & TI_QUIRK_SYSCON_MAY_BE_MISSING && ret == -EIO) {
+ /* not a syscon register! */
+ void __iomem *regs = ioremap(OMAP3_SYSCON_BASE +
+ opp_data->soc_data->efuse_offset, 4);
+@@ -257,7 +263,7 @@ static int ti_cpufreq_get_rev(struct ti_cpufreq_data *opp_data,
+
+ ret = regmap_read(opp_data->syscon, opp_data->soc_data->rev_offset,
+ &revision);
+- if (ret == -EIO) {
++ if (opp_data->soc_data->quirks & TI_QUIRK_SYSCON_MAY_BE_MISSING && ret == -EIO) {
+ /* not a syscon register! */
+ void __iomem *regs = ioremap(OMAP3_SYSCON_BASE +
+ opp_data->soc_data->rev_offset, 4);
+--
+2.43.0
+
--- /dev/null
+From 1fcbfdad1b63b2c7cd1d8f26eeed5ce372fe0b48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jul 2024 14:24:52 +0200
+Subject: crypto: xor - fix template benchmarking
+
+From: Helge Deller <deller@kernel.org>
+
+[ Upstream commit ab9a244c396aae4aaa34b2399b82fc15ec2df8c1 ]
+
+Commit c055e3eae0f1 ("crypto: xor - use ktime for template benchmarking")
+switched from using jiffies to ktime-based performance benchmarking.
+
+This works nicely on machines which have a fine-grained ktime()
+clocksource as e.g. x86 machines with TSC.
+But other machines, e.g. my 4-way HP PARISC server, don't have such
+fine-grained clocksources, which is why it seems that 800 xor loops
+take zero seconds, which then shows up in the logs as:
+
+ xor: measuring software checksum speed
+ 8regs : -1018167296 MB/sec
+ 8regs_prefetch : -1018167296 MB/sec
+ 32regs : -1018167296 MB/sec
+ 32regs_prefetch : -1018167296 MB/sec
+
+Fix this with some small modifications to the existing code to improve
+the algorithm to always produce correct results without introducing
+major delays for architectures with a fine-grained ktime()
+clocksource:
+a) Delay start of the timing until ktime() just advanced. On machines
+with a fast ktime() this should be just one additional ktime() call.
+b) Count the number of loops. Run at minimum 800 loops and finish
+earliest when the ktime() counter has progressed.
+
+With that the throughput can now be calculated more accurately under all
+conditions.
+
+Fixes: c055e3eae0f1 ("crypto: xor - use ktime for template benchmarking")
+Signed-off-by: Helge Deller <deller@gmx.de>
+Tested-by: John David Anglin <dave.anglin@bell.net>
+
+v2:
+- clean up coding style (noticed & suggested by Herbert Xu)
+- rephrased & fixed typo in commit message
+
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ crypto/xor.c | 31 ++++++++++++++-----------------
+ 1 file changed, 14 insertions(+), 17 deletions(-)
+
+diff --git a/crypto/xor.c b/crypto/xor.c
+index 8e72e5d5db0de..56aa3169e8717 100644
+--- a/crypto/xor.c
++++ b/crypto/xor.c
+@@ -83,33 +83,30 @@ static void __init
+ do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2)
+ {
+ int speed;
+- int i, j;
+- ktime_t min, start, diff;
++ unsigned long reps;
++ ktime_t min, start, t0;
+
+ tmpl->next = template_list;
+ template_list = tmpl;
+
+ preempt_disable();
+
+- min = (ktime_t)S64_MAX;
+- for (i = 0; i < 3; i++) {
+- start = ktime_get();
+- for (j = 0; j < REPS; j++) {
+- mb(); /* prevent loop optimization */
+- tmpl->do_2(BENCH_SIZE, b1, b2);
+- mb();
+- }
+- diff = ktime_sub(ktime_get(), start);
+- if (diff < min)
+- min = diff;
+- }
++ reps = 0;
++ t0 = ktime_get();
++ /* delay start until time has advanced */
++ while ((start = ktime_get()) == t0)
++ cpu_relax();
++ do {
++ mb(); /* prevent loop optimization */
++ tmpl->do_2(BENCH_SIZE, b1, b2);
++ mb();
++ } while (reps++ < REPS || (t0 = ktime_get()) == start);
++ min = ktime_sub(t0, start);
+
+ preempt_enable();
+
+ // bytes/ns == GB/s, multiply by 1000 to get MB/s [not MiB/s]
+- if (!min)
+- min = 1;
+- speed = (1000 * REPS * BENCH_SIZE) / (unsigned int)ktime_to_ns(min);
++ speed = (1000 * reps * BENCH_SIZE) / (unsigned int)ktime_to_ns(min);
+ tmpl->speed = speed;
+
+ pr_info(" %-16s: %5d MB/sec\n", tmpl->name, speed);
+--
+2.43.0
+
--- /dev/null
+From bb5964bee8e937036186ce2c64966c24400ba993 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Aug 2024 17:09:27 +0800
+Subject: drivers:drm:exynos_drm_gsc:Fix wrong assignment in gsc_bind()
+
+From: Yuesong Li <liyuesong@vivo.com>
+
+[ Upstream commit 94ebc3d3235c5c516f67315059ce657e5090e94b ]
+
+cocci reported a double assignment problem. Upon reviewing previous
+commits, it appears this may actually be an incorrect assignment.
+
+Fixes: 8b9550344d39 ("drm/ipp: clean up debug messages")
+Signed-off-by: Yuesong Li <liyuesong@vivo.com>
+Signed-off-by: Inki Dae <inki.dae@samsung.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/exynos/exynos_drm_gsc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+index 8c090354fd8a5..d7e0d19c0c025 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+@@ -1173,7 +1173,7 @@ static int gsc_bind(struct device *dev, struct device *master, void *data)
+ struct exynos_drm_ipp *ipp = &ctx->ipp;
+
+ ctx->drm_dev = drm_dev;
+- ctx->drm_dev = drm_dev;
++ ipp->drm_dev = drm_dev;
+ exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv);
+
+ exynos_drm_ipp_register(dev, ipp, &ipp_funcs,
+--
+2.43.0
+
--- /dev/null
+From cb25a96100b3ed72d789d1d20170e95f89970783 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jul 2024 01:50:23 +0800
+Subject: drivers: media: dvb-frontends/rtl2830: fix an out-of-bounds write
+ error
+
+From: Junlin Li <make24@iscas.ac.cn>
+
+[ Upstream commit 46d7ebfe6a75a454a5fa28604f0ef1491f9d8d14 ]
+
+Ensure index in rtl2830_pid_filter does not exceed 31 to prevent
+out-of-bounds access.
+
+dev->filters is a 32-bit value, so set_bit and clear_bit functions should
+only operate on indices from 0 to 31. If index is 32, it will attempt to
+access a non-existent 33rd bit, leading to out-of-bounds access.
+Change the boundary check from index > 32 to index >= 32 to resolve this
+issue.
+
+Fixes: df70ddad81b4 ("[media] rtl2830: implement PID filter")
+Signed-off-by: Junlin Li <make24@iscas.ac.cn>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/dvb-frontends/rtl2830.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/dvb-frontends/rtl2830.c b/drivers/media/dvb-frontends/rtl2830.c
+index e6b8367c8cce4..84c00c6894d3d 100644
+--- a/drivers/media/dvb-frontends/rtl2830.c
++++ b/drivers/media/dvb-frontends/rtl2830.c
+@@ -609,7 +609,7 @@ static int rtl2830_pid_filter(struct dvb_frontend *fe, u8 index, u16 pid, int on
+ index, pid, onoff);
+
+ /* skip invalid PIDs (0x2000) */
+- if (pid > 0x1fff || index > 32)
++ if (pid > 0x1fff || index >= 32)
+ return 0;
+
+ if (onoff)
+--
+2.43.0
+
--- /dev/null
+From 2b857d3a86ee9c4e4b3f9855f7c63357106469ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jul 2024 21:24:13 +0800
+Subject: drivers: media: dvb-frontends/rtl2832: fix an out-of-bounds write
+ error
+
+From: Junlin Li <make24@iscas.ac.cn>
+
+[ Upstream commit 8ae06f360cfaca2b88b98ca89144548b3186aab1 ]
+
+Ensure index in rtl2832_pid_filter does not exceed 31 to prevent
+out-of-bounds access.
+
+dev->filters is a 32-bit value, so set_bit and clear_bit functions should
+only operate on indices from 0 to 31. If index is 32, it will attempt to
+access a non-existent 33rd bit, leading to out-of-bounds access.
+Change the boundary check from index > 32 to index >= 32 to resolve this
+issue.
+
+Signed-off-by: Junlin Li <make24@iscas.ac.cn>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Fixes: 4b01e01a81b6 ("[media] rtl2832: implement PID filter")
+[hverkuil: added fixes tag, rtl2830_pid_filter -> rtl2832_pid_filter in logmsg]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/dvb-frontends/rtl2832.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c
+index dcbeb9f5e12a3..7b0d6be9bf000 100644
+--- a/drivers/media/dvb-frontends/rtl2832.c
++++ b/drivers/media/dvb-frontends/rtl2832.c
+@@ -983,7 +983,7 @@ static int rtl2832_pid_filter(struct dvb_frontend *fe, u8 index, u16 pid,
+ index, pid, onoff, dev->slave_ts);
+
+ /* skip invalid PIDs (0x2000) */
+- if (pid > 0x1fff || index > 32)
++ if (pid > 0x1fff || index >= 32)
+ return 0;
+
+ if (onoff)
+--
+2.43.0
+
--- /dev/null
+From db6a87ab4fd2c360d8136e5796f9e03e94c6dd75 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jul 2024 17:18:17 +0530
+Subject: drm/amd/display: Add null check for set_output_gamma in
+ dcn30_set_output_transfer_func
+
+From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+
+[ Upstream commit 08ae395ea22fb3d9b318c8bde28c0dfd2f5fa4d2 ]
+
+This commit adds a null check for the set_output_gamma function pointer
+in the dcn30_set_output_transfer_func function. Previously,
+set_output_gamma was being checked for nullity at line 386, but then it
+was being dereferenced without any nullity check at line 401. This
+could potentially lead to a null pointer dereference error if
+set_output_gamma is indeed null.
+
+To fix this, we now ensure that set_output_gamma is not null before
+dereferencing it. We do this by adding a nullity check for
+set_output_gamma before the call to set_output_gamma at line 401. If
+set_output_gamma is null, we log an error message and do not call the
+function.
+
+This fix prevents a potential null pointer dereference error.
+
+drivers/gpu/drm/amd/amdgpu/../display/dc/hwss/dcn30/dcn30_hwseq.c:401 dcn30_set_output_transfer_func()
+error: we previously assumed 'mpc->funcs->set_output_gamma' could be null (see line 386)
+
+drivers/gpu/drm/amd/amdgpu/../display/dc/hwss/dcn30/dcn30_hwseq.c
+ 373 bool dcn30_set_output_transfer_func(struct dc *dc,
+ 374 struct pipe_ctx *pipe_ctx,
+ 375 const struct dc_stream_state *stream)
+ 376 {
+ 377 int mpcc_id = pipe_ctx->plane_res.hubp->inst;
+ 378 struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
+ 379 const struct pwl_params *params = NULL;
+ 380 bool ret = false;
+ 381
+ 382 /* program OGAM or 3DLUT only for the top pipe*/
+ 383 if (pipe_ctx->top_pipe == NULL) {
+ 384 /*program rmu shaper and 3dlut in MPC*/
+ 385 ret = dcn30_set_mpc_shaper_3dlut(pipe_ctx, stream);
+ 386 if (ret == false && mpc->funcs->set_output_gamma) {
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If this is NULL
+
+ 387 if (stream->out_transfer_func.type == TF_TYPE_HWPWL)
+ 388 params = &stream->out_transfer_func.pwl;
+ 389 else if (pipe_ctx->stream->out_transfer_func.type ==
+ 390 TF_TYPE_DISTRIBUTED_POINTS &&
+ 391 cm3_helper_translate_curve_to_hw_format(
+ 392 &stream->out_transfer_func,
+ 393 &mpc->blender_params, false))
+ 394 params = &mpc->blender_params;
+ 395 /* there are no ROM LUTs in OUTGAM */
+ 396 if (stream->out_transfer_func.type == TF_TYPE_PREDEFINED)
+ 397 BREAK_TO_DEBUGGER();
+ 398 }
+ 399 }
+ 400
+--> 401 mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Then it will crash
+
+ 402 return ret;
+ 403 }
+
+Fixes: d99f13878d6f ("drm/amd/display: Add DCN3 HWSEQ")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Cc: Tom Chung <chiahsuan.chung@amd.com>
+Cc: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
+Cc: Roman Li <roman.li@amd.com>
+Cc: Hersen Wu <hersenxs.wu@amd.com>
+Cc: Alex Hung <alex.hung@amd.com>
+Cc: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Cc: Harry Wentland <harry.wentland@amd.com>
+Cc: Hamza Mahfooz <hamza.mahfooz@amd.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Reviewed-by: Tom Chung <chiahsuan.chung@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/dcn30/dcn30_hwseq.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+index 8d8114ee67f67..81547178a934d 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+@@ -212,7 +212,11 @@ bool dcn30_set_output_transfer_func(struct dc *dc,
+ }
+ }
+
+- mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
++ if (mpc->funcs->set_output_gamma)
++ mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
++ else
++ DC_LOG_ERROR("%s: set_output_gamma function pointer is NULL.\n", __func__);
++
+ return ret;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From cb661bc2771cfe8536e9919ed6984bee6e7a5eb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jul 2024 13:23:56 -0400
+Subject: drm/amdgpu: properly handle vbios fake edid sizing
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 8155566a26b8d6c1dd914f06a0c652e4e2f2adf1 ]
+
+The comment in the vbios structure says:
+// = 128 means EDID length is 128 bytes, otherwise the EDID length = ucFakeEDIDLength*128
+
+This fake edid struct has not been used in a long time, so I'm
+not sure if there were actually any boards out there with a non-128 byte
+EDID, but align the code with the comment.
+
+Reviewed-by: Thomas Weißschuh <linux@weissschuh.net>
+Reported-by: Thomas Weißschuh <linux@weissschuh.net>
+Link: https://lists.freedesktop.org/archives/amd-gfx/2024-June/109964.html
+Fixes: d38ceaf99ed0 ("drm/amdgpu: add core driver (v4)")
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/amdgpu/atombios_encoders.c | 29 ++++++++++---------
+ 1 file changed, 16 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
+index d3e0bb6d244a4..f32b432283ec6 100644
+--- a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
++++ b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
+@@ -2089,26 +2089,29 @@ amdgpu_atombios_encoder_get_lcd_info(struct amdgpu_encoder *encoder)
+ fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;
+ if (fake_edid_record->ucFakeEDIDLength) {
+ struct edid *edid;
+- int edid_size =
+- max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength);
+- edid = kmalloc(edid_size, GFP_KERNEL);
++ int edid_size;
++
++ if (fake_edid_record->ucFakeEDIDLength == 128)
++ edid_size = fake_edid_record->ucFakeEDIDLength;
++ else
++ edid_size = fake_edid_record->ucFakeEDIDLength * 128;
++ edid = kmemdup(&fake_edid_record->ucFakeEDIDString[0],
++ edid_size, GFP_KERNEL);
+ if (edid) {
+- memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0],
+- fake_edid_record->ucFakeEDIDLength);
+-
+ if (drm_edid_is_valid(edid)) {
+ adev->mode_info.bios_hardcoded_edid = edid;
+ adev->mode_info.bios_hardcoded_edid_size = edid_size;
+- } else
++ } else {
+ kfree(edid);
++ }
+ }
++ record += struct_size(fake_edid_record,
++ ucFakeEDIDString,
++ edid_size);
++ } else {
++ /* empty fake edid record must be 3 bytes long */
++ record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
+ }
+- record += fake_edid_record->ucFakeEDIDLength ?
+- struct_size(fake_edid_record,
+- ucFakeEDIDString,
+- fake_edid_record->ucFakeEDIDLength) :
+- /* empty fake edid record must be 3 bytes long */
+- sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
+ break;
+ case LCD_PANEL_RESOLUTION_RECORD_TYPE:
+ panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;
+--
+2.43.0
+
--- /dev/null
+From 92f0c5af6007633640e7a457741be49d6e8dbd6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Oct 2022 14:30:44 +1300
+Subject: drm/amdgpu: Replace one-element array with flexible-array member
+
+From: Paulo Miguel Almeida <paulo.miguel.almeida.rodenas@gmail.com>
+
+[ Upstream commit 320e2590e281d0a7865e861f50155b5b435e9813 ]
+
+One-element arrays are deprecated, and we are replacing them with
+flexible array members instead. So, replace one-element array with
+flexible-array member in struct _ATOM_FAKE_EDID_PATCH_RECORD and
+refactor the rest of the code accordingly.
+
+Important to mention is that doing a build before/after this patch
+results in no binary output differences.
+
+This helps with the ongoing efforts to tighten the FORTIFY_SOURCE
+routines on memcpy() and help us make progress towards globally
+enabling -fstrict-flex-arrays=3 [1].
+
+Link: https://github.com/KSPP/linux/issues/79
+Link: https://github.com/KSPP/linux/issues/238
+Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101836 [1]
+
+Signed-off-by: Paulo Miguel Almeida <paulo.miguel.almeida.rodenas@gmail.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 8155566a26b8 ("drm/amdgpu: properly handle vbios fake edid sizing")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/atombios_encoders.c | 7 +++++--
+ drivers/gpu/drm/amd/include/atombios.h | 2 +-
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
+index 6134ed9640279..d3e0bb6d244a4 100644
+--- a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
++++ b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
+@@ -2104,8 +2104,11 @@ amdgpu_atombios_encoder_get_lcd_info(struct amdgpu_encoder *encoder)
+ }
+ }
+ record += fake_edid_record->ucFakeEDIDLength ?
+- fake_edid_record->ucFakeEDIDLength + 2 :
+- sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
++ struct_size(fake_edid_record,
++ ucFakeEDIDString,
++ fake_edid_record->ucFakeEDIDLength) :
++ /* empty fake edid record must be 3 bytes long */
++ sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
+ break;
+ case LCD_PANEL_RESOLUTION_RECORD_TYPE:
+ panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;
+diff --git a/drivers/gpu/drm/amd/include/atombios.h b/drivers/gpu/drm/amd/include/atombios.h
+index 6a505d1b82a52..0c2637519f4d0 100644
+--- a/drivers/gpu/drm/amd/include/atombios.h
++++ b/drivers/gpu/drm/amd/include/atombios.h
+@@ -4107,7 +4107,7 @@ typedef struct _ATOM_FAKE_EDID_PATCH_RECORD
+ {
+ UCHAR ucRecordType;
+ UCHAR ucFakeEDIDLength; // = 128 means EDID length is 128 bytes, otherwise the EDID length = ucFakeEDIDLength*128
+- UCHAR ucFakeEDIDString[1]; // This actually has ucFakeEdidLength elements.
++ UCHAR ucFakeEDIDString[]; // This actually has ucFakeEdidLength elements.
+ } ATOM_FAKE_EDID_PATCH_RECORD;
+
+ typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD
+--
+2.43.0
+
--- /dev/null
+From 49e8b2eb3491cb2f30e641a4e5ecc1804c36ed90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Aug 2024 17:16:37 +0800
+Subject: drm/bridge: lontium-lt8912b: Validate mode in
+ drm_bridge_funcs::mode_valid()
+
+From: Liu Ying <victor.liu@nxp.com>
+
+[ Upstream commit fe828fbd87786238b30f44cafd698d975d956c97 ]
+
+If the bridge is attached with the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag set,
+this driver won't initialize a connector and hence display mode won't be
+validated in drm_connector_helper_funcs::mode_valid(). So, move the mode
+validation from drm_connector_helper_funcs::mode_valid() to
+drm_bridge_funcs::mode_valid(), because the mode validation is always done
+for the bridge.
+
+Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge")
+Signed-off-by: Liu Ying <victor.liu@nxp.com>
+Reviewed-by: Robert Foss <rfoss@kernel.org>
+Signed-off-by: Robert Foss <rfoss@kernel.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240813091637.1054586-1-victor.liu@nxp.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/lontium-lt8912b.c | 35 ++++++++++++------------
+ 1 file changed, 18 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+index 6379d5c8edff1..9dd52282a055e 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c
++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c
+@@ -401,22 +401,6 @@ static const struct drm_connector_funcs lt8912_connector_funcs = {
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+ };
+
+-static enum drm_mode_status
+-lt8912_connector_mode_valid(struct drm_connector *connector,
+- struct drm_display_mode *mode)
+-{
+- if (mode->clock > 150000)
+- return MODE_CLOCK_HIGH;
+-
+- if (mode->hdisplay > 1920)
+- return MODE_BAD_HVALUE;
+-
+- if (mode->vdisplay > 1080)
+- return MODE_BAD_VVALUE;
+-
+- return MODE_OK;
+-}
+-
+ static int lt8912_connector_get_modes(struct drm_connector *connector)
+ {
+ struct edid *edid;
+@@ -444,7 +428,6 @@ static int lt8912_connector_get_modes(struct drm_connector *connector)
+
+ static const struct drm_connector_helper_funcs lt8912_connector_helper_funcs = {
+ .get_modes = lt8912_connector_get_modes,
+- .mode_valid = lt8912_connector_mode_valid,
+ };
+
+ static void lt8912_bridge_mode_set(struct drm_bridge *bridge,
+@@ -590,6 +573,23 @@ static void lt8912_bridge_detach(struct drm_bridge *bridge)
+ drm_bridge_hpd_disable(lt->hdmi_port);
+ }
+
++static enum drm_mode_status
++lt8912_bridge_mode_valid(struct drm_bridge *bridge,
++ const struct drm_display_info *info,
++ const struct drm_display_mode *mode)
++{
++ if (mode->clock > 150000)
++ return MODE_CLOCK_HIGH;
++
++ if (mode->hdisplay > 1920)
++ return MODE_BAD_HVALUE;
++
++ if (mode->vdisplay > 1080)
++ return MODE_BAD_VVALUE;
++
++ return MODE_OK;
++}
++
+ static enum drm_connector_status
+ lt8912_bridge_detect(struct drm_bridge *bridge)
+ {
+@@ -620,6 +620,7 @@ static struct edid *lt8912_bridge_get_edid(struct drm_bridge *bridge,
+ static const struct drm_bridge_funcs lt8912_bridge_funcs = {
+ .attach = lt8912_bridge_attach,
+ .detach = lt8912_bridge_detach,
++ .mode_valid = lt8912_bridge_mode_valid,
+ .mode_set = lt8912_bridge_mode_set,
+ .enable = lt8912_bridge_enable,
+ .detect = lt8912_bridge_detect,
+--
+2.43.0
+
--- /dev/null
+From ab50c7768185c5393379e7ceb2170f1d79335f8a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Aug 2024 18:14:47 +0800
+Subject: drm/mediatek: Use spin_lock_irqsave() for CRTC event lock
+
+From: Fei Shao <fshao@chromium.org>
+
+[ Upstream commit be03b30b7aa99aca876fbc7c1c1b73b2d0339321 ]
+
+Use the state-aware spin_lock_irqsave() and spin_unlock_irqrestore()
+to avoid unconditionally re-enabling the local interrupts.
+
+Fixes: 411f5c1eacfe ("drm/mediatek: handle events when enabling/disabling crtc")
+Signed-off-by: Fei Shao <fshao@chromium.org>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20240828101511.3269822-1-fshao@chromium.org/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+index 1a038fa004668..27f3e91425580 100644
+--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
++++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+@@ -386,6 +386,7 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
+ {
+ struct drm_device *drm = mtk_crtc->base.dev;
+ struct drm_crtc *crtc = &mtk_crtc->base;
++ unsigned long flags;
+ int i;
+
+ for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
+@@ -412,10 +413,10 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
+ pm_runtime_put(drm->dev);
+
+ if (crtc->state->event && !crtc->state->active) {
+- spin_lock_irq(&crtc->dev->event_lock);
++ spin_lock_irqsave(&crtc->dev->event_lock, flags);
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ crtc->state->event = NULL;
+- spin_unlock_irq(&crtc->dev->event_lock);
++ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+ }
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 61b1de5262b98a5195e104a341cb1c794ab311c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Sep 2024 13:54:00 +0000
+Subject: drm/msm/a5xx: disable preemption in submits by default
+
+From: Vladimir Lypak <vladimir.lypak@gmail.com>
+
+[ Upstream commit db9dec2db76146d65e1cfbb6afb2e2bd5dab67f8 ]
+
+Fine grain preemption (switching from/to points within submits)
+requires extra handling in command stream of those submits, especially
+when rendering with tiling (using GMEM). However this handling is
+missing at this point in mesa (and always was). For this reason we get
+random GPU faults and hangs if more than one priority level is used
+because local preemption is enabled prior to executing command stream
+from submit.
+With that said it was ahead of time to enable local preemption by
+default considering the fact that even on downstream kernel it is only
+enabled if requested via UAPI.
+
+Fixes: a7a4c19c36de ("drm/msm/a5xx: fix setting of the CP_PREEMPT_ENABLE_LOCAL register")
+Signed-off-by: Vladimir Lypak <vladimir.lypak@gmail.com>
+Patchwork: https://patchwork.freedesktop.org/patch/612041/
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+index e9c8111122bd6..22aa05d08f5ea 100644
+--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+@@ -152,9 +152,13 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+ OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1);
+ OUT_RING(ring, 1);
+
+- /* Enable local preemption for finegrain preemption */
++ /*
++ * Disable local preemption by default because it requires
++ * user-space to be aware of it and provide additional handling
++ * to restore rendering state or do various flushes on switch.
++ */
+ OUT_PKT7(ring, CP_PREEMPT_ENABLE_LOCAL, 1);
+- OUT_RING(ring, 0x1);
++ OUT_RING(ring, 0x0);
+
+ /* Allow CP_CONTEXT_SWITCH_YIELD packets in the IB2 */
+ OUT_PKT7(ring, CP_YIELD_ENABLE, 1);
+--
+2.43.0
+
--- /dev/null
+From 03ac68fb27f53e975fb1e90e821df46dfb256f6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Sep 2024 13:54:02 +0000
+Subject: drm/msm/a5xx: fix races in preemption evaluation stage
+
+From: Vladimir Lypak <vladimir.lypak@gmail.com>
+
+[ Upstream commit ce050f307ad93bcc5958d0dd35fc276fd394d274 ]
+
+On A5XX GPUs when preemption is used it's invietable to enter a soft
+lock-up state in which GPU is stuck at empty ring-buffer doing nothing.
+This appears as full UI lockup and not detected as GPU hang (because
+it's not). This happens due to not triggering preemption when it was
+needed. Sometimes this state can be recovered by some new submit but
+generally it won't happen because applications are waiting for old
+submits to retire.
+
+One of the reasons why this happens is a race between a5xx_submit and
+a5xx_preempt_trigger called from IRQ during submit retire. Former thread
+updates ring->cur of previously empty and not current ring right after
+latter checks it for emptiness. Then both threads can just exit because
+for first one preempt_state wasn't NONE yet and for second one all rings
+appeared to be empty.
+
+To prevent such situations from happening we need to establish guarantee
+for preempt_trigger to make decision after each submit or retire. To
+implement this we serialize preemption initiation using spinlock. If
+switch is already in progress we need to re-trigger preemption when it
+finishes.
+
+Fixes: b1fc2839d2f9 ("drm/msm: Implement preemption for A5XX targets")
+Signed-off-by: Vladimir Lypak <vladimir.lypak@gmail.com>
+Patchwork: https://patchwork.freedesktop.org/patch/612045/
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/a5xx_gpu.h | 1 +
+ drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 24 +++++++++++++++++++++--
+ 2 files changed, 23 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
+index c7187bcc5e908..b4d06ca3e499d 100644
+--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
++++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
+@@ -36,6 +36,7 @@ struct a5xx_gpu {
+ uint64_t preempt_iova[MSM_GPU_MAX_RINGS];
+
+ atomic_t preempt_state;
++ spinlock_t preempt_start_lock;
+ struct timer_list preempt_timer;
+
+ struct drm_gem_object *shadow_bo;
+diff --git a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
+index 79b43803b6141..6bce363dc1ece 100644
+--- a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
++++ b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
+@@ -97,12 +97,19 @@ void a5xx_preempt_trigger(struct msm_gpu *gpu)
+ if (gpu->nr_rings == 1)
+ return;
+
++ /*
++ * Serialize preemption start to ensure that we always make
++ * decision on latest state. Otherwise we can get stuck in
++ * lower priority or empty ring.
++ */
++ spin_lock_irqsave(&a5xx_gpu->preempt_start_lock, flags);
++
+ /*
+ * Try to start preemption by moving from NONE to START. If
+ * unsuccessful, a preemption is already in flight
+ */
+ if (!try_preempt_state(a5xx_gpu, PREEMPT_NONE, PREEMPT_START))
+- return;
++ goto out;
+
+ /* Get the next ring to preempt to */
+ ring = get_next_ring(gpu);
+@@ -127,9 +134,11 @@ void a5xx_preempt_trigger(struct msm_gpu *gpu)
+ set_preempt_state(a5xx_gpu, PREEMPT_ABORT);
+ update_wptr(gpu, a5xx_gpu->cur_ring);
+ set_preempt_state(a5xx_gpu, PREEMPT_NONE);
+- return;
++ goto out;
+ }
+
++ spin_unlock_irqrestore(&a5xx_gpu->preempt_start_lock, flags);
++
+ /* Make sure the wptr doesn't update while we're in motion */
+ spin_lock_irqsave(&ring->preempt_lock, flags);
+ a5xx_gpu->preempt[ring->id]->wptr = get_wptr(ring);
+@@ -153,6 +162,10 @@ void a5xx_preempt_trigger(struct msm_gpu *gpu)
+
+ /* And actually start the preemption */
+ gpu_write(gpu, REG_A5XX_CP_CONTEXT_SWITCH_CNTL, 1);
++ return;
++
++out:
++ spin_unlock_irqrestore(&a5xx_gpu->preempt_start_lock, flags);
+ }
+
+ void a5xx_preempt_irq(struct msm_gpu *gpu)
+@@ -189,6 +202,12 @@ void a5xx_preempt_irq(struct msm_gpu *gpu)
+ update_wptr(gpu, a5xx_gpu->cur_ring);
+
+ set_preempt_state(a5xx_gpu, PREEMPT_NONE);
++
++ /*
++ * Try to trigger preemption again in case there was a submit or
++ * retire during ring switch
++ */
++ a5xx_preempt_trigger(gpu);
+ }
+
+ void a5xx_preempt_hw_init(struct msm_gpu *gpu)
+@@ -302,5 +321,6 @@ void a5xx_preempt_init(struct msm_gpu *gpu)
+ }
+ }
+
++ spin_lock_init(&a5xx_gpu->preempt_start_lock);
+ timer_setup(&a5xx_gpu->preempt_timer, a5xx_preempt_timer, 0);
+ }
+--
+2.43.0
+
--- /dev/null
+From f6b18a362d699e56b22de4005dc32abbcadec3ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Sep 2024 13:54:01 +0000
+Subject: drm/msm/a5xx: properly clear preemption records on resume
+
+From: Vladimir Lypak <vladimir.lypak@gmail.com>
+
+[ Upstream commit 64fd6d01a52904bdbda0ce810a45a428c995a4ca ]
+
+Two fields of preempt_record which are used by CP aren't reset on
+resume: "data" and "info". This is the reason behind faults which happen
+when we try to switch to the ring that was active last before suspend.
+In addition those faults can't be recovered from because we use suspend
+and resume to do so (keeping values of those fields again).
+
+Fixes: b1fc2839d2f9 ("drm/msm: Implement preemption for A5XX targets")
+Signed-off-by: Vladimir Lypak <vladimir.lypak@gmail.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/612043/
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
+index e0eef47dae632..79b43803b6141 100644
+--- a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
++++ b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
+@@ -205,6 +205,8 @@ void a5xx_preempt_hw_init(struct msm_gpu *gpu)
+ return;
+
+ for (i = 0; i < gpu->nr_rings; i++) {
++ a5xx_gpu->preempt[i]->data = 0;
++ a5xx_gpu->preempt[i]->info = 0;
+ a5xx_gpu->preempt[i]->wptr = 0;
+ a5xx_gpu->preempt[i]->rptr = 0;
+ a5xx_gpu->preempt[i]->rbase = gpu->rb[i]->iova;
+--
+2.43.0
+
--- /dev/null
+From b4e8b700fa757580c71ecf502a059c4dc655a66e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Sep 2024 13:54:03 +0000
+Subject: drm/msm/a5xx: workaround early ring-buffer emptiness check
+
+From: Vladimir Lypak <vladimir.lypak@gmail.com>
+
+[ Upstream commit a30f9f65b5ac82d4390548c32ed9c7f05de7ddf5 ]
+
+There is another cause for soft lock-up of GPU in empty ring-buffer:
+race between GPU executing last commands and CPU checking ring for
+emptiness. On GPU side IRQ for retire is triggered by CACHE_FLUSH_TS
+event and RPTR shadow (which is used to check ring emptiness) is updated
+a bit later from CP_CONTEXT_SWITCH_YIELD. Thus if GPU is executing its
+last commands slow enough or we check that ring too fast we will miss a
+chance to trigger switch to lower priority ring because current ring isn't
+empty just yet. This can escalate to lock-up situation described in
+previous patch.
+To work-around this issue we keep track of last submit sequence number
+for each ring and compare it with one written to memptrs from GPU during
+execution of CACHE_FLUSH_TS event.
+
+Fixes: b1fc2839d2f9 ("drm/msm: Implement preemption for A5XX targets")
+Signed-off-by: Vladimir Lypak <vladimir.lypak@gmail.com>
+Patchwork: https://patchwork.freedesktop.org/patch/612047/
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 4 ++++
+ drivers/gpu/drm/msm/adreno/a5xx_gpu.h | 1 +
+ drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 4 ++++
+ 3 files changed, 9 insertions(+)
+
+diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+index 1f48d561f39b9..4548dda8a2fc0 100644
+--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+@@ -65,6 +65,8 @@ void a5xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring,
+
+ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+ {
++ struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
++ struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+ struct msm_ringbuffer *ring = submit->ring;
+ struct msm_gem_object *obj;
+ uint32_t *ptr, dwords;
+@@ -109,6 +111,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit
+ }
+ }
+
++ a5xx_gpu->last_seqno[ring->id] = submit->seqno;
+ a5xx_flush(gpu, ring, true);
+ a5xx_preempt_trigger(gpu);
+
+@@ -210,6 +213,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+ /* Write the fence to the scratch register */
+ OUT_PKT4(ring, REG_A5XX_CP_SCRATCH_REG(2), 1);
+ OUT_RING(ring, submit->seqno);
++ a5xx_gpu->last_seqno[ring->id] = submit->seqno;
+
+ /*
+ * Execute a CACHE_FLUSH_TS event. This will ensure that the
+diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
+index b4d06ca3e499d..9c0d701fe4b85 100644
+--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
++++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
+@@ -34,6 +34,7 @@ struct a5xx_gpu {
+ struct drm_gem_object *preempt_counters_bo[MSM_GPU_MAX_RINGS];
+ struct a5xx_preempt_record *preempt[MSM_GPU_MAX_RINGS];
+ uint64_t preempt_iova[MSM_GPU_MAX_RINGS];
++ uint32_t last_seqno[MSM_GPU_MAX_RINGS];
+
+ atomic_t preempt_state;
+ spinlock_t preempt_start_lock;
+diff --git a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
+index 6bce363dc1ece..a9fb75521b8a6 100644
+--- a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
++++ b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
+@@ -55,6 +55,8 @@ static inline void update_wptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
+ /* Return the highest priority ringbuffer with something in it */
+ static struct msm_ringbuffer *get_next_ring(struct msm_gpu *gpu)
+ {
++ struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
++ struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+ unsigned long flags;
+ int i;
+
+@@ -64,6 +66,8 @@ static struct msm_ringbuffer *get_next_ring(struct msm_gpu *gpu)
+
+ spin_lock_irqsave(&ring->preempt_lock, flags);
+ empty = (get_wptr(ring) == gpu->funcs->get_rptr(gpu, ring));
++ if (!empty && ring == a5xx_gpu->cur_ring)
++ empty = ring->memptrs->fence == a5xx_gpu->last_seqno[i];
+ spin_unlock_irqrestore(&ring->preempt_lock, flags);
+
+ if (!empty)
+--
+2.43.0
+
--- /dev/null
+From d4521241b716e24cf5a8c46839fc9402a732bd20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Nov 2021 10:11:02 -0800
+Subject: drm/msm: Drop priv->lastctx
+
+From: Rob Clark <robdclark@chromium.org>
+
+[ Upstream commit 1d054c9b8457b56a651109fac21f56f46ccd46b2 ]
+
+cur_ctx_seqno already does the same thing, but handles the edge cases
+where a refcnt'd context can live after lastclose. So let's not have
+two ways to do the same thing.
+
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Reviewed-by: Akhil P Oommen <akhilpo@codeaurora.org>
+Link: https://lore.kernel.org/r/20211109181117.591148-3-robdclark@gmail.com
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Stable-dep-of: a30f9f65b5ac ("drm/msm/a5xx: workaround early ring-buffer emptiness check")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/a2xx_gpu.c | 3 +--
+ drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 3 +--
+ drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 3 +--
+ drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 8 +++-----
+ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 9 +++------
+ drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 10 ----------
+ drivers/gpu/drm/msm/msm_drv.c | 6 ------
+ drivers/gpu/drm/msm/msm_drv.h | 2 +-
+ drivers/gpu/drm/msm/msm_gpu.c | 2 +-
+ drivers/gpu/drm/msm/msm_gpu.h | 11 +++++++++++
+ 10 files changed, 22 insertions(+), 35 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
+index 17d6a1ecb1110..b4ca5985f015a 100644
+--- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
+@@ -12,7 +12,6 @@ static bool a2xx_idle(struct msm_gpu *gpu);
+
+ static void a2xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+ {
+- struct msm_drm_private *priv = gpu->dev->dev_private;
+ struct msm_ringbuffer *ring = submit->ring;
+ unsigned int i;
+
+@@ -23,7 +22,7 @@ static void a2xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+ break;
+ case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
+ /* ignore if there has not been a ctx switch: */
+- if (priv->lastctx == submit->queue->ctx)
++ if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
+ break;
+ fallthrough;
+ case MSM_SUBMIT_CMD_BUF:
+diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+index 8fb847c174ff8..2e481e2692ba9 100644
+--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+@@ -30,7 +30,6 @@ static bool a3xx_idle(struct msm_gpu *gpu);
+
+ static void a3xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+ {
+- struct msm_drm_private *priv = gpu->dev->dev_private;
+ struct msm_ringbuffer *ring = submit->ring;
+ unsigned int i;
+
+@@ -41,7 +40,7 @@ static void a3xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+ break;
+ case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
+ /* ignore if there has not been a ctx switch: */
+- if (priv->lastctx == submit->queue->ctx)
++ if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
+ break;
+ fallthrough;
+ case MSM_SUBMIT_CMD_BUF:
+diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+index a96ee79cc5e08..c5524d6e8705c 100644
+--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+@@ -24,7 +24,6 @@ static bool a4xx_idle(struct msm_gpu *gpu);
+
+ static void a4xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+ {
+- struct msm_drm_private *priv = gpu->dev->dev_private;
+ struct msm_ringbuffer *ring = submit->ring;
+ unsigned int i;
+
+@@ -35,7 +34,7 @@ static void a4xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+ break;
+ case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
+ /* ignore if there has not been a ctx switch: */
+- if (priv->lastctx == submit->queue->ctx)
++ if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
+ break;
+ fallthrough;
+ case MSM_SUBMIT_CMD_BUF:
+diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+index 22aa05d08f5ea..1f48d561f39b9 100644
+--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+@@ -65,7 +65,6 @@ void a5xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring,
+
+ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+ {
+- struct msm_drm_private *priv = gpu->dev->dev_private;
+ struct msm_ringbuffer *ring = submit->ring;
+ struct msm_gem_object *obj;
+ uint32_t *ptr, dwords;
+@@ -76,7 +75,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit
+ case MSM_SUBMIT_CMD_IB_TARGET_BUF:
+ break;
+ case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
+- if (priv->lastctx == submit->queue->ctx)
++ if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
+ break;
+ fallthrough;
+ case MSM_SUBMIT_CMD_BUF:
+@@ -126,12 +125,11 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+ {
+ struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+ struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+- struct msm_drm_private *priv = gpu->dev->dev_private;
+ struct msm_ringbuffer *ring = submit->ring;
+ unsigned int i, ibs = 0;
+
+ if (IS_ENABLED(CONFIG_DRM_MSM_GPU_SUDO) && submit->in_rb) {
+- priv->lastctx = NULL;
++ gpu->cur_ctx_seqno = 0;
+ a5xx_submit_in_rb(gpu, submit);
+ return;
+ }
+@@ -170,7 +168,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+ case MSM_SUBMIT_CMD_IB_TARGET_BUF:
+ break;
+ case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
+- if (priv->lastctx == submit->queue->ctx)
++ if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
+ break;
+ fallthrough;
+ case MSM_SUBMIT_CMD_BUF:
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+index 2d07c02c59f14..27fae0dc97040 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+@@ -106,7 +106,7 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
+ u32 asid;
+ u64 memptr = rbmemptr(ring, ttbr0);
+
+- if (ctx->seqno == a6xx_gpu->cur_ctx_seqno)
++ if (ctx->seqno == a6xx_gpu->base.base.cur_ctx_seqno)
+ return;
+
+ if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid))
+@@ -138,14 +138,11 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
+
+ OUT_PKT7(ring, CP_EVENT_WRITE, 1);
+ OUT_RING(ring, 0x31);
+-
+- a6xx_gpu->cur_ctx_seqno = ctx->seqno;
+ }
+
+ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+ {
+ unsigned int index = submit->seqno % MSM_GPU_SUBMIT_STATS_COUNT;
+- struct msm_drm_private *priv = gpu->dev->dev_private;
+ struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+ struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+ struct msm_ringbuffer *ring = submit->ring;
+@@ -177,7 +174,7 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+ case MSM_SUBMIT_CMD_IB_TARGET_BUF:
+ break;
+ case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
+- if (priv->lastctx == submit->queue->ctx)
++ if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
+ break;
+ fallthrough;
+ case MSM_SUBMIT_CMD_BUF:
+@@ -1085,7 +1082,7 @@ static int hw_init(struct msm_gpu *gpu)
+ /* Always come up on rb 0 */
+ a6xx_gpu->cur_ring = gpu->rb[0];
+
+- a6xx_gpu->cur_ctx_seqno = 0;
++ gpu->cur_ctx_seqno = 0;
+
+ /* Enable the SQE_to start the CP engine */
+ gpu_write(gpu, REG_A6XX_CP_SQE_CNTL, 1);
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
+index 8e5527c881b1e..86e0a7c3fe6df 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
+@@ -20,16 +20,6 @@ struct a6xx_gpu {
+
+ struct msm_ringbuffer *cur_ring;
+
+- /**
+- * cur_ctx_seqno:
+- *
+- * The ctx->seqno value of the context with current pgtables
+- * installed. Tracked by seqno rather than pointer value to
+- * avoid dangling pointers, and cases where a ctx can be freed
+- * and a new one created with the same address.
+- */
+- int cur_ctx_seqno;
+-
+ struct a6xx_gmu gmu;
+
+ struct drm_gem_object *shadow_bo;
+diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
+index e238d2beb7abe..8e6a9d0d85e59 100644
+--- a/drivers/gpu/drm/msm/msm_drv.c
++++ b/drivers/gpu/drm/msm/msm_drv.c
+@@ -732,14 +732,8 @@ static void context_close(struct msm_file_private *ctx)
+
+ static void msm_postclose(struct drm_device *dev, struct drm_file *file)
+ {
+- struct msm_drm_private *priv = dev->dev_private;
+ struct msm_file_private *ctx = file->driver_priv;
+
+- mutex_lock(&dev->struct_mutex);
+- if (ctx == priv->lastctx)
+- priv->lastctx = NULL;
+- mutex_unlock(&dev->struct_mutex);
+-
+ context_close(ctx);
+ }
+
+diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
+index 8488e49817e1e..164605f0103b1 100644
+--- a/drivers/gpu/drm/msm/msm_drv.h
++++ b/drivers/gpu/drm/msm/msm_drv.h
+@@ -157,7 +157,7 @@ struct msm_drm_private {
+
+ /* when we have more than one 'msm_gpu' these need to be an array: */
+ struct msm_gpu *gpu;
+- struct msm_file_private *lastctx;
++
+ /* gpu is only set on open(), but we need this info earlier */
+ bool is_a2xx;
+ bool has_cached_coherent;
+diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
+index a2f21b89d077c..8250d86d11e7a 100644
+--- a/drivers/gpu/drm/msm/msm_gpu.c
++++ b/drivers/gpu/drm/msm/msm_gpu.c
+@@ -763,7 +763,7 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+ mutex_unlock(&gpu->active_lock);
+
+ gpu->funcs->submit(gpu, submit);
+- priv->lastctx = submit->queue->ctx;
++ gpu->cur_ctx_seqno = submit->queue->ctx->seqno;
+
+ hangcheck_timer_reset(gpu);
+ }
+diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
+index 461ff5a5aa5bb..bb37878258c8c 100644
+--- a/drivers/gpu/drm/msm/msm_gpu.h
++++ b/drivers/gpu/drm/msm/msm_gpu.h
+@@ -137,6 +137,17 @@ struct msm_gpu {
+ struct msm_ringbuffer *rb[MSM_GPU_MAX_RINGS];
+ int nr_rings;
+
++ /**
++ * cur_ctx_seqno:
++ *
++ * The ctx->seqno value of the last context to submit rendering,
++ * and the one with current pgtables installed (for generations
++ * that support per-context pgtables). Tracked by seqno rather
++ * than pointer value to avoid dangling pointers, and cases where
++ * a ctx can be freed and a new one created with the same address.
++ */
++ int cur_ctx_seqno;
++
+ /*
+ * List of GEM active objects on this gpu. Protected by
+ * msm_drm_private::mm_lock
+--
+2.43.0
+
--- /dev/null
+From dc40227456d7756636f024c5c9adc920195a05b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jul 2024 12:13:12 +0300
+Subject: drm/msm: Fix incorrect file name output in adreno_request_fw()
+
+From: Aleksandr Mishin <amishin@t-argos.ru>
+
+[ Upstream commit e19366911340c2313a1abbb09c54eaf9bdea4f58 ]
+
+In adreno_request_fw() when debugging information is printed to the log
+after firmware load, an incorrect filename is printed. 'newname' is used
+instead of 'fwname', so prefix "qcom/" is being added to filename.
+Looks like "copy-paste" mistake.
+
+Fix this mistake by replacing 'newname' with 'fwname'.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 2c41ef1b6f7d ("drm/msm/adreno: deal with linux-firmware fw paths")
+Signed-off-by: Aleksandr Mishin <amishin@t-argos.ru>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Patchwork: https://patchwork.freedesktop.org/patch/602382/
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/adreno_gpu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+index 4c61f99068083..2377a1bbbb800 100644
+--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+@@ -321,7 +321,7 @@ adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname)
+ ret = request_firmware_direct(&fw, fwname, drm->dev);
+ if (!ret) {
+ DRM_DEV_INFO(drm->dev, "loaded %s from legacy location\n",
+- newname);
++ fwname);
+ adreno_gpu->fwloc = FW_LOCATION_LEGACY;
+ goto out;
+ } else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) {
+--
+2.43.0
+
--- /dev/null
+From a988bd5eeadf8a8c46d44c7a473e3357cdf2ca69 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Aug 2024 09:53:37 -0700
+Subject: drm/msm: fix %s null argument error
+
+From: Sherry Yang <sherry.yang@oracle.com>
+
+[ Upstream commit 25b85075150fe8adddb096db8a4b950353045ee1 ]
+
+The following build error was triggered because of NULL string argument:
+
+BUILDSTDERR: drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c: In function 'mdp5_smp_dump':
+BUILDSTDERR: drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c:352:51: error: '%s' directive argument is null [-Werror=format-overflow=]
+BUILDSTDERR: 352 | drm_printf(p, "%s:%d\t%d\t%s\n",
+BUILDSTDERR: | ^~
+BUILDSTDERR: drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c:352:51: error: '%s' directive argument is null [-Werror=format-overflow=]
+
+This happens from the commit a61ddb4393ad ("drm: enable (most) W=1
+warnings by default across the subsystem"). Using "(null)" instead
+to fix it.
+
+Fixes: bc5289eed481 ("drm/msm/mdp5: add debugfs to show smp block status")
+Signed-off-by: Sherry Yang <sherry.yang@oracle.com>
+Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
+Patchwork: https://patchwork.freedesktop.org/patch/611071/
+Link: https://lore.kernel.org/r/20240827165337.1075904-1-sherry.yang@oracle.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
+index d7fa2c49e7410..45820ac1a5254 100644
+--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
+@@ -356,7 +356,7 @@ void mdp5_smp_dump(struct mdp5_smp *smp, struct drm_printer *p)
+
+ drm_printf(p, "%s:%d\t%d\t%s\n",
+ pipe2name(pipe), j, inuse,
+- plane ? plane->name : NULL);
++ plane ? plane->name : "(null)");
+
+ total += inuse;
+ }
+--
+2.43.0
+
--- /dev/null
+From 3faf87f516bc884e6c2c059496df185bc96e3ab5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Aug 2024 10:19:04 -0700
+Subject: drm/radeon/evergreen_cs: fix int overflow errors in cs track offsets
+
+From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+
+[ Upstream commit 3fbaf475a5b8361ebee7da18964db809e37518b7 ]
+
+Several cs track offsets (such as 'track->db_s_read_offset')
+either are initialized with or plainly take big enough values that,
+once shifted 8 bits left, may be hit with integer overflow if the
+resulting values end up going over u32 limit.
+
+Same goes for a few instances of 'surf.layer_size * mslice'
+multiplications that are added to 'offset' variable - they may
+potentially overflow as well and need to be validated properly.
+
+While some debug prints in this code section take possible overflow
+issues into account, simply casting to (unsigned long) may be
+erroneous in its own way, as depending on CPU architecture one is
+liable to get different results.
+
+Fix said problems by:
+ - casting 'offset' to fixed u64 data type instead of
+ ambiguous unsigned long.
+ - casting one of the operands in vulnerable to integer
+ overflow cases to u64.
+ - adjust format specifiers in debug prints to properly
+ represent 'offset' values.
+
+Found by Linux Verification Center (linuxtesting.org) with static
+analysis tool SVACE.
+
+Fixes: 285484e2d55e ("drm/radeon: add support for evergreen/ni tiling informations v11")
+Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/evergreen_cs.c | 62 +++++++++++++--------------
+ 1 file changed, 31 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
+index 0de79f3a7e3ff..820c2c3641d38 100644
+--- a/drivers/gpu/drm/radeon/evergreen_cs.c
++++ b/drivers/gpu/drm/radeon/evergreen_cs.c
+@@ -395,7 +395,7 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
+ struct evergreen_cs_track *track = p->track;
+ struct eg_surface surf;
+ unsigned pitch, slice, mslice;
+- unsigned long offset;
++ u64 offset;
+ int r;
+
+ mslice = G_028C6C_SLICE_MAX(track->cb_color_view[id]) + 1;
+@@ -433,14 +433,14 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
+ return r;
+ }
+
+- offset = track->cb_color_bo_offset[id] << 8;
++ offset = (u64)track->cb_color_bo_offset[id] << 8;
+ if (offset & (surf.base_align - 1)) {
+- dev_warn(p->dev, "%s:%d cb[%d] bo base %ld not aligned with %ld\n",
++ dev_warn(p->dev, "%s:%d cb[%d] bo base %llu not aligned with %ld\n",
+ __func__, __LINE__, id, offset, surf.base_align);
+ return -EINVAL;
+ }
+
+- offset += surf.layer_size * mslice;
++ offset += (u64)surf.layer_size * mslice;
+ if (offset > radeon_bo_size(track->cb_color_bo[id])) {
+ /* old ddx are broken they allocate bo with w*h*bpp but
+ * program slice with ALIGN(h, 8), catch this and patch
+@@ -448,14 +448,14 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
+ */
+ if (!surf.mode) {
+ uint32_t *ib = p->ib.ptr;
+- unsigned long tmp, nby, bsize, size, min = 0;
++ u64 tmp, nby, bsize, size, min = 0;
+
+ /* find the height the ddx wants */
+ if (surf.nby > 8) {
+ min = surf.nby - 8;
+ }
+ bsize = radeon_bo_size(track->cb_color_bo[id]);
+- tmp = track->cb_color_bo_offset[id] << 8;
++ tmp = (u64)track->cb_color_bo_offset[id] << 8;
+ for (nby = surf.nby; nby > min; nby--) {
+ size = nby * surf.nbx * surf.bpe * surf.nsamples;
+ if ((tmp + size * mslice) <= bsize) {
+@@ -467,7 +467,7 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
+ slice = ((nby * surf.nbx) / 64) - 1;
+ if (!evergreen_surface_check(p, &surf, "cb")) {
+ /* check if this one works */
+- tmp += surf.layer_size * mslice;
++ tmp += (u64)surf.layer_size * mslice;
+ if (tmp <= bsize) {
+ ib[track->cb_color_slice_idx[id]] = slice;
+ goto old_ddx_ok;
+@@ -476,9 +476,9 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
+ }
+ }
+ dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, "
+- "offset %d, max layer %d, bo size %ld, slice %d)\n",
++ "offset %llu, max layer %d, bo size %ld, slice %d)\n",
+ __func__, __LINE__, id, surf.layer_size,
+- track->cb_color_bo_offset[id] << 8, mslice,
++ (u64)track->cb_color_bo_offset[id] << 8, mslice,
+ radeon_bo_size(track->cb_color_bo[id]), slice);
+ dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n",
+ __func__, __LINE__, surf.nbx, surf.nby,
+@@ -562,7 +562,7 @@ static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
+ struct evergreen_cs_track *track = p->track;
+ struct eg_surface surf;
+ unsigned pitch, slice, mslice;
+- unsigned long offset;
++ u64 offset;
+ int r;
+
+ mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1;
+@@ -608,18 +608,18 @@ static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
+ return r;
+ }
+
+- offset = track->db_s_read_offset << 8;
++ offset = (u64)track->db_s_read_offset << 8;
+ if (offset & (surf.base_align - 1)) {
+- dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n",
++ dev_warn(p->dev, "%s:%d stencil read bo base %llu not aligned with %ld\n",
+ __func__, __LINE__, offset, surf.base_align);
+ return -EINVAL;
+ }
+- offset += surf.layer_size * mslice;
++ offset += (u64)surf.layer_size * mslice;
+ if (offset > radeon_bo_size(track->db_s_read_bo)) {
+ dev_warn(p->dev, "%s:%d stencil read bo too small (layer size %d, "
+- "offset %ld, max layer %d, bo size %ld)\n",
++ "offset %llu, max layer %d, bo size %ld)\n",
+ __func__, __LINE__, surf.layer_size,
+- (unsigned long)track->db_s_read_offset << 8, mslice,
++ (u64)track->db_s_read_offset << 8, mslice,
+ radeon_bo_size(track->db_s_read_bo));
+ dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n",
+ __func__, __LINE__, track->db_depth_size,
+@@ -627,18 +627,18 @@ static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
+ return -EINVAL;
+ }
+
+- offset = track->db_s_write_offset << 8;
++ offset = (u64)track->db_s_write_offset << 8;
+ if (offset & (surf.base_align - 1)) {
+- dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n",
++ dev_warn(p->dev, "%s:%d stencil write bo base %llu not aligned with %ld\n",
+ __func__, __LINE__, offset, surf.base_align);
+ return -EINVAL;
+ }
+- offset += surf.layer_size * mslice;
++ offset += (u64)surf.layer_size * mslice;
+ if (offset > radeon_bo_size(track->db_s_write_bo)) {
+ dev_warn(p->dev, "%s:%d stencil write bo too small (layer size %d, "
+- "offset %ld, max layer %d, bo size %ld)\n",
++ "offset %llu, max layer %d, bo size %ld)\n",
+ __func__, __LINE__, surf.layer_size,
+- (unsigned long)track->db_s_write_offset << 8, mslice,
++ (u64)track->db_s_write_offset << 8, mslice,
+ radeon_bo_size(track->db_s_write_bo));
+ return -EINVAL;
+ }
+@@ -659,7 +659,7 @@ static int evergreen_cs_track_validate_depth(struct radeon_cs_parser *p)
+ struct evergreen_cs_track *track = p->track;
+ struct eg_surface surf;
+ unsigned pitch, slice, mslice;
+- unsigned long offset;
++ u64 offset;
+ int r;
+
+ mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1;
+@@ -706,34 +706,34 @@ static int evergreen_cs_track_validate_depth(struct radeon_cs_parser *p)
+ return r;
+ }
+
+- offset = track->db_z_read_offset << 8;
++ offset = (u64)track->db_z_read_offset << 8;
+ if (offset & (surf.base_align - 1)) {
+- dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n",
++ dev_warn(p->dev, "%s:%d stencil read bo base %llu not aligned with %ld\n",
+ __func__, __LINE__, offset, surf.base_align);
+ return -EINVAL;
+ }
+- offset += surf.layer_size * mslice;
++ offset += (u64)surf.layer_size * mslice;
+ if (offset > radeon_bo_size(track->db_z_read_bo)) {
+ dev_warn(p->dev, "%s:%d depth read bo too small (layer size %d, "
+- "offset %ld, max layer %d, bo size %ld)\n",
++ "offset %llu, max layer %d, bo size %ld)\n",
+ __func__, __LINE__, surf.layer_size,
+- (unsigned long)track->db_z_read_offset << 8, mslice,
++ (u64)track->db_z_read_offset << 8, mslice,
+ radeon_bo_size(track->db_z_read_bo));
+ return -EINVAL;
+ }
+
+- offset = track->db_z_write_offset << 8;
++ offset = (u64)track->db_z_write_offset << 8;
+ if (offset & (surf.base_align - 1)) {
+- dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n",
++ dev_warn(p->dev, "%s:%d stencil write bo base %llu not aligned with %ld\n",
+ __func__, __LINE__, offset, surf.base_align);
+ return -EINVAL;
+ }
+- offset += surf.layer_size * mslice;
++ offset += (u64)surf.layer_size * mslice;
+ if (offset > radeon_bo_size(track->db_z_write_bo)) {
+ dev_warn(p->dev, "%s:%d depth write bo too small (layer size %d, "
+- "offset %ld, max layer %d, bo size %ld)\n",
++ "offset %llu, max layer %d, bo size %ld)\n",
+ __func__, __LINE__, surf.layer_size,
+- (unsigned long)track->db_z_write_offset << 8, mslice,
++ (u64)track->db_z_write_offset << 8, mslice,
+ radeon_bo_size(track->db_z_write_bo));
+ return -EINVAL;
+ }
+--
+2.43.0
+
--- /dev/null
+From 35476ca11cf4cdfb027c3d611f9c097d7e1d2a86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jul 2024 13:31:58 -0400
+Subject: drm/radeon: properly handle vbios fake edid sizing
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 17c6baff3d5f65c8da164137a58742541a060b2f ]
+
+The comment in the vbios structure says:
+// = 128 means EDID length is 128 bytes, otherwise the EDID length = ucFakeEDIDLength*128
+
+This fake edid struct has not been used in a long time, so I'm
+not sure if there were actually any boards out there with a non-128 byte
+EDID, but align the code with the comment.
+
+Reviewed-by: Thomas Weißschuh <linux@weissschuh.net>
+Reported-by: Thomas Weißschuh <linux@weissschuh.net>
+Link: https://lists.freedesktop.org/archives/amd-gfx/2024-June/109964.html
+Fixes: c324acd5032f ("drm/radeon/kms: parse the extended LCD info block")
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/radeon_atombios.c | 29 +++++++++++++-----------
+ 1 file changed, 16 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
+index c591e4326b13c..7ab38317d8e70 100644
+--- a/drivers/gpu/drm/radeon/radeon_atombios.c
++++ b/drivers/gpu/drm/radeon/radeon_atombios.c
+@@ -1714,26 +1714,29 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
+ fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;
+ if (fake_edid_record->ucFakeEDIDLength) {
+ struct edid *edid;
+- int edid_size =
+- max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength);
+- edid = kmalloc(edid_size, GFP_KERNEL);
++ int edid_size;
++
++ if (fake_edid_record->ucFakeEDIDLength == 128)
++ edid_size = fake_edid_record->ucFakeEDIDLength;
++ else
++ edid_size = fake_edid_record->ucFakeEDIDLength * 128;
++ edid = kmemdup(&fake_edid_record->ucFakeEDIDString[0],
++ edid_size, GFP_KERNEL);
+ if (edid) {
+- memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0],
+- fake_edid_record->ucFakeEDIDLength);
+-
+ if (drm_edid_is_valid(edid)) {
+ rdev->mode_info.bios_hardcoded_edid = edid;
+ rdev->mode_info.bios_hardcoded_edid_size = edid_size;
+- } else
++ } else {
+ kfree(edid);
++ }
+ }
++ record += struct_size(fake_edid_record,
++ ucFakeEDIDString,
++ edid_size);
++ } else {
++ /* empty fake edid record must be 3 bytes long */
++ record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
+ }
+- record += fake_edid_record->ucFakeEDIDLength ?
+- struct_size(fake_edid_record,
+- ucFakeEDIDString,
+- fake_edid_record->ucFakeEDIDLength) :
+- /* empty fake edid record must be 3 bytes long */
+- sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
+ break;
+ case LCD_PANEL_RESOLUTION_RECORD_TYPE:
+ panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;
+--
+2.43.0
+
--- /dev/null
+From 2039dd8beaf3fb296b3f2b6e3dd5cd191727b2e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Oct 2022 16:32:05 +1300
+Subject: drm/radeon: Replace one-element array with flexible-array member
+
+From: Paulo Miguel Almeida <paulo.miguel.almeida.rodenas@gmail.com>
+
+[ Upstream commit c81c5bd5cf2f428867e0bcfcccd4e4d2f8c68f51 ]
+
+One-element arrays are deprecated, and we are replacing them with
+flexible array members instead. So, replace one-element array with
+flexible-array member in struct _ATOM_FAKE_EDID_PATCH_RECORD and
+refactor the rest of the code accordingly.
+
+It's worth mentioning that doing a build before/after this patch results
+in no binary output differences.
+
+This helps with the ongoing efforts to tighten the FORTIFY_SOURCE
+routines on memcpy() and help us make progress towards globally
+enabling -fstrict-flex-arrays=3 [1].
+
+Link: https://github.com/KSPP/linux/issues/79
+Link: https://github.com/KSPP/linux/issues/239
+Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101836 [1]
+
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Paulo Miguel Almeida <paulo.miguel.almeida.rodenas@gmail.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 17c6baff3d5f ("drm/radeon: properly handle vbios fake edid sizing")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/radeon/atombios.h | 2 +-
+ drivers/gpu/drm/radeon/radeon_atombios.c | 7 +++++--
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h
+index 83e8b8547f9be..5e86cab431246 100644
+--- a/drivers/gpu/drm/radeon/atombios.h
++++ b/drivers/gpu/drm/radeon/atombios.h
+@@ -3615,7 +3615,7 @@ typedef struct _ATOM_FAKE_EDID_PATCH_RECORD
+ {
+ UCHAR ucRecordType;
+ UCHAR ucFakeEDIDLength;
+- UCHAR ucFakeEDIDString[1]; // This actually has ucFakeEdidLength elements.
++ UCHAR ucFakeEDIDString[]; // This actually has ucFakeEdidLength elements.
+ } ATOM_FAKE_EDID_PATCH_RECORD;
+
+ typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD
+diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
+index 28c4413f4dc8d..c591e4326b13c 100644
+--- a/drivers/gpu/drm/radeon/radeon_atombios.c
++++ b/drivers/gpu/drm/radeon/radeon_atombios.c
+@@ -1729,8 +1729,11 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
+ }
+ }
+ record += fake_edid_record->ucFakeEDIDLength ?
+- fake_edid_record->ucFakeEDIDLength + 2 :
+- sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
++ struct_size(fake_edid_record,
++ ucFakeEDIDString,
++ fake_edid_record->ucFakeEDIDLength) :
++ /* empty fake edid record must be 3 bytes long */
++ sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
+ break;
+ case LCD_PANEL_RESOLUTION_RECORD_TYPE:
+ panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;
+--
+2.43.0
+
--- /dev/null
+From dca27752efc8986fd4b5f062bdeac87955d7d4a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Jun 2024 17:03:55 +0000
+Subject: drm/rockchip: dw_hdmi: Fix reading EDID when using a forced mode
+
+From: Jonas Karlman <jonas@kwiboo.se>
+
+[ Upstream commit a5d024541ec466f428e6c514577d511a40779c7b ]
+
+EDID cannot be read on RK3328 until after read_hpd has been called and
+correct io voltage has been configured based on connection status.
+
+When a forced mode is used, e.g. video=1920x1080@60e, the connector
+detect ops, that in turn normally calls the read_hpd, never gets called.
+
+This result in reading EDID to fail in connector get_modes ops.
+
+Call dw_hdmi_rk3328_read_hpd at end of dw_hdmi_rk3328_setup_hpd to
+correct io voltage and allow reading EDID after setup_hpd.
+
+Fixes: 1c53ba8f22a1 ("drm/rockchip: dw_hdmi: add dw-hdmi support for the rk3328")
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240615170417.3134517-5-jonas@kwiboo.se
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+index 8677c82716784..9e1c34af53909 100644
+--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+@@ -389,6 +389,8 @@ static void dw_hdmi_rk3328_setup_hpd(struct dw_hdmi *dw_hdmi, void *data)
+ HIWORD_UPDATE(RK3328_HDMI_SDAIN_MSK | RK3328_HDMI_SCLIN_MSK,
+ RK3328_HDMI_SDAIN_MSK | RK3328_HDMI_SCLIN_MSK |
+ RK3328_HDMI_HPD_IOE));
++
++ dw_hdmi_rk3328_read_hpd(dw_hdmi, data);
+ }
+
+ static const struct dw_hdmi_phy_ops rk3228_hdmi_phy_ops = {
+--
+2.43.0
+
--- /dev/null
+From 1f77750370d85d5cdaf9ecb92a63983b6449d8a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Jun 2024 17:03:54 +0000
+Subject: drm/rockchip: vop: Allow 4096px width scaling
+
+From: Alex Bee <knaerzche@gmail.com>
+
+[ Upstream commit 0ef968d91a20b5da581839f093f98f7a03a804f7 ]
+
+There is no reason to limit VOP scaling to 3840px width, the limit of
+RK3288, when there are newer VOP versions that support 4096px width.
+
+Change to enforce a maximum of 4096px width plane scaling, the maximum
+supported output width of the VOP versions supported by this driver.
+
+Fixes: 4c156c21c794 ("drm/rockchip: vop: support plane scale")
+Signed-off-by: Alex Bee <knaerzche@gmail.com>
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240615170417.3134517-4-jonas@kwiboo.se
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+index c7106f1165466..c9056bf8659ad 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+@@ -371,8 +371,8 @@ static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *win,
+ if (info->is_yuv)
+ is_yuv = true;
+
+- if (dst_w > 3840) {
+- DRM_DEV_ERROR(vop->dev, "Maximum dst width (3840) exceeded\n");
++ if (dst_w > 4096) {
++ DRM_DEV_ERROR(vop->dev, "Maximum dst width (4096) exceeded\n");
+ return;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From fbf3bc6a51b56ddcfb37053f785cd7cfdb20d9b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 6 Jan 2024 17:54:32 +0100
+Subject: drm/stm: Fix an error handling path in stm_drm_platform_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit ce7c90bfda2656418c69ba0dd8f8a7536b8928d4 ]
+
+If drm_dev_register() fails, a call to drv_load() must be undone, as
+already done in the remove function.
+
+Fixes: b759012c5fa7 ("drm/stm: Add STM32 LTDC driver")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Acked-by: Raphael Gallais-Pou <raphael.gallais-pou@foss.st.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20fff7f853f20a48a96db8ff186124470ec4d976.1704560028.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Raphael Gallais-Pou <raphael.gallais-pou@foss.st.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/stm/drv.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
+index 222869b232ae0..d8f4d1150913b 100644
+--- a/drivers/gpu/drm/stm/drv.c
++++ b/drivers/gpu/drm/stm/drv.c
+@@ -195,12 +195,14 @@ static int stm_drm_platform_probe(struct platform_device *pdev)
+
+ ret = drm_dev_register(ddev, 0);
+ if (ret)
+- goto err_put;
++ goto err_unload;
+
+ drm_fbdev_generic_setup(ddev, 16);
+
+ return 0;
+
++err_unload:
++ drv_unload(ddev);
+ err_put:
+ drm_dev_put(ddev);
+
+--
+2.43.0
+
--- /dev/null
+From b97d60bc2941afb58fd9ad826f61f16d6c9543b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Oct 2021 14:07:07 -0500
+Subject: EDAC/synopsys: Add support for version 3 of the Synopsys EDAC DDR
+
+From: Dinh Nguyen <dinguyen@kernel.org>
+
+[ Upstream commit f7824ded41491d7ebc156a3a2f6fa05cd89da7c2 ]
+
+Add support for version 3.80a of the Synopsys DDR controller. This
+version of the controller has the following differences:
+
+- UE/CE are auto cleared
+- Interrupts are supported by default
+
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Michal Simek <michal.simek@xilinx.com>
+Link: https://lkml.kernel.org/r/20211012190709.1504152-2-dinguyen@kernel.org
+Stable-dep-of: 35e6dbfe1846 ("EDAC/synopsys: Fix error injection on Zynq UltraScale+")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/synopsys_edac.c | 49 ++++++++++++++++++++++++++++++------
+ 1 file changed, 42 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
+index 8557781bb8dce..40b1abeca8562 100644
+--- a/drivers/edac/synopsys_edac.c
++++ b/drivers/edac/synopsys_edac.c
+@@ -101,6 +101,7 @@
+ /* DDR ECC Quirks */
+ #define DDR_ECC_INTR_SUPPORT BIT(0)
+ #define DDR_ECC_DATA_POISON_SUPPORT BIT(1)
++#define DDR_ECC_INTR_SELF_CLEAR BIT(2)
+
+ /* ZynqMP Enhanced DDR memory controller registers that are relevant to ECC */
+ /* ECC Configuration Registers */
+@@ -176,6 +177,10 @@
+ #define DDR_QOS_IRQ_EN_OFST 0x20208
+ #define DDR_QOS_IRQ_DB_OFST 0x2020C
+
++/* DDR QOS Interrupt register definitions */
++#define DDR_UE_MASK BIT(9)
++#define DDR_CE_MASK BIT(8)
++
+ /* ECC Corrected Error Register Mask and Shifts*/
+ #define ECC_CEADDR0_RW_MASK 0x3FFFF
+ #define ECC_CEADDR0_RNK_MASK BIT(24)
+@@ -539,10 +544,16 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
+ priv = mci->pvt_info;
+ p_data = priv->p_data;
+
+- regval = readl(priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
+- regval &= (DDR_QOSCE_MASK | DDR_QOSUE_MASK);
+- if (!(regval & ECC_CE_UE_INTR_MASK))
+- return IRQ_NONE;
++ /*
++ * v3.0 of the controller has the ce/ue bits cleared automatically,
++ * so this condition does not apply.
++ */
++ if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)) {
++ regval = readl(priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
++ regval &= (DDR_QOSCE_MASK | DDR_QOSUE_MASK);
++ if (!(regval & ECC_CE_UE_INTR_MASK))
++ return IRQ_NONE;
++ }
+
+ status = p_data->get_error_info(priv);
+ if (status)
+@@ -554,7 +565,9 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
+
+ edac_dbg(3, "Total error count CE %d UE %d\n",
+ priv->ce_cnt, priv->ue_cnt);
+- writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
++ /* v3.0 of the controller does not have this register */
++ if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR))
++ writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
+ return IRQ_HANDLED;
+ }
+
+@@ -840,8 +853,13 @@ static void mc_init(struct mem_ctl_info *mci, struct platform_device *pdev)
+ static void enable_intr(struct synps_edac_priv *priv)
+ {
+ /* Enable UE/CE Interrupts */
+- writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
+- priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
++ if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
++ writel(DDR_UE_MASK | DDR_CE_MASK,
++ priv->baseaddr + ECC_CLR_OFST);
++ else
++ writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
++ priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
++
+ }
+
+ static void disable_intr(struct synps_edac_priv *priv)
+@@ -896,6 +914,19 @@ static const struct synps_platform_data zynqmp_edac_def = {
+ ),
+ };
+
++static const struct synps_platform_data synopsys_edac_def = {
++ .get_error_info = zynqmp_get_error_info,
++ .get_mtype = zynqmp_get_mtype,
++ .get_dtype = zynqmp_get_dtype,
++ .get_ecc_state = zynqmp_get_ecc_state,
++ .quirks = (DDR_ECC_INTR_SUPPORT | DDR_ECC_INTR_SELF_CLEAR
++#ifdef CONFIG_EDAC_DEBUG
++ | DDR_ECC_DATA_POISON_SUPPORT
++#endif
++ ),
++};
++
++
+ static const struct of_device_id synps_edac_match[] = {
+ {
+ .compatible = "xlnx,zynq-ddrc-a05",
+@@ -905,6 +936,10 @@ static const struct of_device_id synps_edac_match[] = {
+ .compatible = "xlnx,zynqmp-ddrc-2.40a",
+ .data = (void *)&zynqmp_edac_def
+ },
++ {
++ .compatible = "snps,ddrc-3.80a",
++ .data = (void *)&synopsys_edac_def
++ },
+ {
+ /* end of table */
+ }
+--
+2.43.0
+
--- /dev/null
+From 98d12e70fdeea0ba43d1d47249e5842b4f2302ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Feb 2024 21:12:46 +0300
+Subject: EDAC/synopsys: Fix ECC status and IRQ control race condition
+
+From: Serge Semin <fancer.lancer@gmail.com>
+
+[ Upstream commit 591c946675d88dcc0ae9ff54be9d5caaee8ce1e3 ]
+
+The race condition around the ECCCLR register access happens in the IRQ
+disable method called in the device remove() procedure and in the ECC IRQ
+handler:
+
+ 1. Enable IRQ:
+ a. ECCCLR = EN_CE | EN_UE
+ 2. Disable IRQ:
+ a. ECCCLR = 0
+ 3. IRQ handler:
+ a. ECCCLR = CLR_CE | CLR_CE_CNT | CLR_CE | CLR_CE_CNT
+ b. ECCCLR = 0
+ c. ECCCLR = EN_CE | EN_UE
+
+So if the IRQ disabling procedure is called concurrently with the IRQ
+handler method the IRQ might be actually left enabled due to the
+statement 3c.
+
+The root cause of the problem is that ECCCLR register (which since
+v3.10a has been called as ECCCTL) has intermixed ECC status data clear
+flags and the IRQ enable/disable flags. Thus the IRQ disabling (clear EN
+flags) and handling (write 1 to clear ECC status data) procedures must
+be serialised around the ECCCTL register modification to prevent the
+race.
+
+So fix the problem described above by adding the spin-lock around the
+ECCCLR modifications and preventing the IRQ-handler from modifying the
+IRQs enable flags (there is no point in disabling the IRQ and then
+re-enabling it again within a single IRQ handler call, see the
+statements 3a/3b and 3c above).
+
+Fixes: f7824ded4149 ("EDAC/synopsys: Add support for version 3 of the Synopsys EDAC DDR")
+Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Link: https://lore.kernel.org/r/20240222181324.28242-2-fancer.lancer@gmail.com
+Stable-dep-of: 35e6dbfe1846 ("EDAC/synopsys: Fix error injection on Zynq UltraScale+")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/synopsys_edac.c | 50 ++++++++++++++++++++++++++----------
+ 1 file changed, 37 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
+index a14baeca64004..feb203efcffff 100644
+--- a/drivers/edac/synopsys_edac.c
++++ b/drivers/edac/synopsys_edac.c
+@@ -22,6 +22,7 @@
+ #include <linux/edac.h>
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
++#include <linux/spinlock.h>
+ #include <linux/interrupt.h>
+ #include <linux/of.h>
+ #include <linux/of_device.h>
+@@ -313,6 +314,7 @@ struct synps_ecc_status {
+ /**
+ * struct synps_edac_priv - DDR memory controller private instance data.
+ * @baseaddr: Base address of the DDR controller.
++ * @reglock: Concurrent CSRs access lock.
+ * @message: Buffer for framing the event specific info.
+ * @stat: ECC status information.
+ * @p_data: Platform data.
+@@ -327,6 +329,7 @@ struct synps_ecc_status {
+ */
+ struct synps_edac_priv {
+ void __iomem *baseaddr;
++ spinlock_t reglock;
+ char message[SYNPS_EDAC_MSG_SIZE];
+ struct synps_ecc_status stat;
+ const struct synps_platform_data *p_data;
+@@ -422,7 +425,8 @@ static int zynq_get_error_info(struct synps_edac_priv *priv)
+ static int zynqmp_get_error_info(struct synps_edac_priv *priv)
+ {
+ struct synps_ecc_status *p;
+- u32 regval, clearval = 0;
++ u32 regval, clearval;
++ unsigned long flags;
+ void __iomem *base;
+
+ base = priv->baseaddr;
+@@ -466,10 +470,14 @@ static int zynqmp_get_error_info(struct synps_edac_priv *priv)
+ p->ueinfo.blknr = (regval & ECC_CEADDR1_BLKNR_MASK);
+ p->ueinfo.data = readl(base + ECC_UESYND0_OFST);
+ out:
+- clearval = ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_CE_ERRCNT;
+- clearval |= ECC_CTRL_CLR_UE_ERR | ECC_CTRL_CLR_UE_ERRCNT;
++ spin_lock_irqsave(&priv->reglock, flags);
++
++ clearval = readl(base + ECC_CLR_OFST) |
++ ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_CE_ERRCNT |
++ ECC_CTRL_CLR_UE_ERR | ECC_CTRL_CLR_UE_ERRCNT;
+ writel(clearval, base + ECC_CLR_OFST);
+- writel(0x0, base + ECC_CLR_OFST);
++
++ spin_unlock_irqrestore(&priv->reglock, flags);
+
+ return 0;
+ }
+@@ -529,24 +537,41 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p)
+
+ static void enable_intr(struct synps_edac_priv *priv)
+ {
++ unsigned long flags;
++
+ /* Enable UE/CE Interrupts */
+- if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
+- writel(DDR_UE_MASK | DDR_CE_MASK,
+- priv->baseaddr + ECC_CLR_OFST);
+- else
++ if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)) {
+ writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
+ priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
+
++ return;
++ }
++
++ spin_lock_irqsave(&priv->reglock, flags);
++
++ writel(DDR_UE_MASK | DDR_CE_MASK,
++ priv->baseaddr + ECC_CLR_OFST);
++
++ spin_unlock_irqrestore(&priv->reglock, flags);
+ }
+
+ static void disable_intr(struct synps_edac_priv *priv)
+ {
++ unsigned long flags;
++
+ /* Disable UE/CE Interrupts */
+- if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
+- writel(0x0, priv->baseaddr + ECC_CLR_OFST);
+- else
++ if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)) {
+ writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
+ priv->baseaddr + DDR_QOS_IRQ_DB_OFST);
++
++ return;
++ }
++
++ spin_lock_irqsave(&priv->reglock, flags);
++
++ writel(0, priv->baseaddr + ECC_CLR_OFST);
++
++ spin_unlock_irqrestore(&priv->reglock, flags);
+ }
+
+ /**
+@@ -590,8 +615,6 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
+ /* v3.0 of the controller does not have this register */
+ if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR))
+ writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
+- else
+- enable_intr(priv);
+
+ return IRQ_HANDLED;
+ }
+@@ -1373,6 +1396,7 @@ static int mc_probe(struct platform_device *pdev)
+ priv = mci->pvt_info;
+ priv->baseaddr = baseaddr;
+ priv->p_data = p_data;
++ spin_lock_init(&priv->reglock);
+
+ mc_init(mci, pdev);
+
+--
+2.43.0
+
--- /dev/null
+From 1151add1426e231663d85a8dca0cb95d63c15d10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jul 2024 15:36:56 +0530
+Subject: EDAC/synopsys: Fix error injection on Zynq UltraScale+
+
+From: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
+
+[ Upstream commit 35e6dbfe1846caeafabb49b7575adb36b0aa2269 ]
+
+The Zynq UltraScale+ MPSoC DDR has a disjoint memory from 2GB to 32GB.
+The DDR host interface has a contiguous memory so while injecting
+errors, the driver should remove the hole else the injection fails as
+the address translation is incorrect.
+
+Introduce a get_mem_info() function pointer and set it for Zynq
+UltraScale+ platform to return host address.
+
+Fixes: 1a81361f75d8 ("EDAC, synopsys: Add Error Injection support for ZynqMP DDR controller")
+Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Link: https://lore.kernel.org/r/20240711100656.31376-1-shubhrajyoti.datta@amd.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/synopsys_edac.c | 35 ++++++++++++++++++++++++++++++++++-
+ 1 file changed, 34 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
+index feb203efcffff..e8ddb029f10d8 100644
+--- a/drivers/edac/synopsys_edac.c
++++ b/drivers/edac/synopsys_edac.c
+@@ -23,6 +23,7 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/spinlock.h>
++#include <linux/sizes.h>
+ #include <linux/interrupt.h>
+ #include <linux/of.h>
+ #include <linux/of_device.h>
+@@ -351,6 +352,7 @@ struct synps_edac_priv {
+ * @get_mtype: Get mtype.
+ * @get_dtype: Get dtype.
+ * @get_ecc_state: Get ECC state.
++ * @get_mem_info: Get EDAC memory info
+ * @quirks: To differentiate IPs.
+ */
+ struct synps_platform_data {
+@@ -358,6 +360,9 @@ struct synps_platform_data {
+ enum mem_type (*get_mtype)(const void __iomem *base);
+ enum dev_type (*get_dtype)(const void __iomem *base);
+ bool (*get_ecc_state)(void __iomem *base);
++#ifdef CONFIG_EDAC_DEBUG
++ u64 (*get_mem_info)(struct synps_edac_priv *priv);
++#endif
+ int quirks;
+ };
+
+@@ -416,6 +421,25 @@ static int zynq_get_error_info(struct synps_edac_priv *priv)
+ return 0;
+ }
+
++#ifdef CONFIG_EDAC_DEBUG
++/**
++ * zynqmp_get_mem_info - Get the current memory info.
++ * @priv: DDR memory controller private instance data.
++ *
++ * Return: host interface address.
++ */
++static u64 zynqmp_get_mem_info(struct synps_edac_priv *priv)
++{
++ u64 hif_addr = 0, linear_addr;
++
++ linear_addr = priv->poison_addr;
++ if (linear_addr >= SZ_32G)
++ linear_addr = linear_addr - SZ_32G + SZ_2G;
++ hif_addr = linear_addr >> 3;
++ return hif_addr;
++}
++#endif
++
+ /**
+ * zynqmp_get_error_info - Get the current ECC error info.
+ * @priv: DDR memory controller private instance data.
+@@ -936,6 +960,9 @@ static const struct synps_platform_data zynqmp_edac_def = {
+ .get_mtype = zynqmp_get_mtype,
+ .get_dtype = zynqmp_get_dtype,
+ .get_ecc_state = zynqmp_get_ecc_state,
++#ifdef CONFIG_EDAC_DEBUG
++ .get_mem_info = zynqmp_get_mem_info,
++#endif
+ .quirks = (DDR_ECC_INTR_SUPPORT
+ #ifdef CONFIG_EDAC_DEBUG
+ | DDR_ECC_DATA_POISON_SUPPORT
+@@ -989,10 +1016,16 @@ MODULE_DEVICE_TABLE(of, synps_edac_match);
+ static void ddr_poison_setup(struct synps_edac_priv *priv)
+ {
+ int col = 0, row = 0, bank = 0, bankgrp = 0, rank = 0, regval;
++ const struct synps_platform_data *p_data;
+ int index;
+ ulong hif_addr = 0;
+
+- hif_addr = priv->poison_addr >> 3;
++ p_data = priv->p_data;
++
++ if (p_data->get_mem_info)
++ hif_addr = p_data->get_mem_info(priv);
++ else
++ hif_addr = priv->poison_addr >> 3;
+
+ for (index = 0; index < DDR_MAX_ROW_SHIFT; index++) {
+ if (priv->row_shift[index])
+--
+2.43.0
+
--- /dev/null
+From 3e735cb01e2ca35a682f5636877cb8b914b14a01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Apr 2022 09:51:37 +0800
+Subject: EDAC/synopsys: Re-enable the error interrupts on v3 hw
+
+From: Sherry Sun <sherry.sun@nxp.com>
+
+[ Upstream commit 4bcffe941758ee17becb43af3b25487f848f6512 ]
+
+zynqmp_get_error_info() writes 0 to the ECC_CLR_OFST register after
+an interrupt for a {un-,}correctable error is raised, which disables
+the error interrupts. Then the interrupt handler will be called only
+once. Therefore, re-enable the error interrupt line at the end of
+intr_handler() for v3.x Synopsys EDAC DDR.
+
+Fixes: f7824ded4149 ("EDAC/synopsys: Add support for version 3 of the Synopsys EDAC DDR")
+Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Shubhrajyoti Datta <Shubhrajyoti.datta@xilinx.com>
+Acked-by: Michal Simek <michal.simek@xilinx.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20220427015137.8406-3-sherry.sun@nxp.com
+Stable-dep-of: 35e6dbfe1846 ("EDAC/synopsys: Fix error injection on Zynq UltraScale+")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/synopsys_edac.c | 47 +++++++++++++++++++-----------------
+ 1 file changed, 25 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
+index 88a481043d4c3..a14baeca64004 100644
+--- a/drivers/edac/synopsys_edac.c
++++ b/drivers/edac/synopsys_edac.c
+@@ -527,6 +527,28 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p)
+ memset(p, 0, sizeof(*p));
+ }
+
++static void enable_intr(struct synps_edac_priv *priv)
++{
++ /* Enable UE/CE Interrupts */
++ if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
++ writel(DDR_UE_MASK | DDR_CE_MASK,
++ priv->baseaddr + ECC_CLR_OFST);
++ else
++ writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
++ priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
++
++}
++
++static void disable_intr(struct synps_edac_priv *priv)
++{
++ /* Disable UE/CE Interrupts */
++ if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
++ writel(0x0, priv->baseaddr + ECC_CLR_OFST);
++ else
++ writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
++ priv->baseaddr + DDR_QOS_IRQ_DB_OFST);
++}
++
+ /**
+ * intr_handler - Interrupt Handler for ECC interrupts.
+ * @irq: IRQ number.
+@@ -568,6 +590,9 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
+ /* v3.0 of the controller does not have this register */
+ if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR))
+ writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
++ else
++ enable_intr(priv);
++
+ return IRQ_HANDLED;
+ }
+
+@@ -850,28 +875,6 @@ static void mc_init(struct mem_ctl_info *mci, struct platform_device *pdev)
+ init_csrows(mci);
+ }
+
+-static void enable_intr(struct synps_edac_priv *priv)
+-{
+- /* Enable UE/CE Interrupts */
+- if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
+- writel(DDR_UE_MASK | DDR_CE_MASK,
+- priv->baseaddr + ECC_CLR_OFST);
+- else
+- writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
+- priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
+-
+-}
+-
+-static void disable_intr(struct synps_edac_priv *priv)
+-{
+- /* Disable UE/CE Interrupts */
+- if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
+- writel(0x0, priv->baseaddr + ECC_CLR_OFST);
+- else
+- writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
+- priv->baseaddr + DDR_QOS_IRQ_DB_OFST);
+-}
+-
+ static int setup_irq(struct mem_ctl_info *mci,
+ struct platform_device *pdev)
+ {
+--
+2.43.0
+
--- /dev/null
+From 214cf685d9b29337c6a53aad113cfafbd6dee6aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Apr 2022 09:51:36 +0800
+Subject: EDAC/synopsys: Use the correct register to disable the error
+ interrupt on v3 hw
+
+From: Sherry Sun <sherry.sun@nxp.com>
+
+[ Upstream commit be76ceaf03bc04e74be5e28f608316b73c2b04ad ]
+
+v3.x Synopsys EDAC DDR doesn't have the QOS Interrupt register. Use the
+ECC Clear Register to disable the error interrupts instead.
+
+Fixes: f7824ded4149 ("EDAC/synopsys: Add support for version 3 of the Synopsys EDAC DDR")
+Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Shubhrajyoti Datta <Shubhrajyoti.datta@xilinx.com>
+Acked-by: Michal Simek <michal.simek@xilinx.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20220427015137.8406-2-sherry.sun@nxp.com
+Stable-dep-of: 35e6dbfe1846 ("EDAC/synopsys: Fix error injection on Zynq UltraScale+")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/edac/synopsys_edac.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
+index 40b1abeca8562..88a481043d4c3 100644
+--- a/drivers/edac/synopsys_edac.c
++++ b/drivers/edac/synopsys_edac.c
+@@ -865,8 +865,11 @@ static void enable_intr(struct synps_edac_priv *priv)
+ static void disable_intr(struct synps_edac_priv *priv)
+ {
+ /* Disable UE/CE Interrupts */
+- writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
+- priv->baseaddr + DDR_QOS_IRQ_DB_OFST);
++ if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
++ writel(0x0, priv->baseaddr + ECC_CLR_OFST);
++ else
++ writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
++ priv->baseaddr + DDR_QOS_IRQ_DB_OFST);
+ }
+
+ static int setup_irq(struct mem_ctl_info *mci,
+--
+2.43.0
+
--- /dev/null
+From 241adbfa0a85660158917a9add20467c741e76da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Aug 2024 21:22:28 +0800
+Subject: ext4: avoid buffer_head leak in ext4_mark_inode_used()
+
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+
+[ Upstream commit 5e5b2a56c57def1b41efd49596621504d7bcc61c ]
+
+Release inode_bitmap_bh from ext4_read_inode_bitmap() in
+ext4_mark_inode_used() to avoid buffer_head leak.
+By the way, remove unneeded goto for invalid ino when inode_bitmap_bh
+is NULL.
+
+Fixes: 8016e29f4362 ("ext4: fast commit recovery path")
+Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
+Link: https://patch.msgid.link/20240820132234.2759926-2-shikemeng@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/ialloc.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
+index 745d781da8915..4478ba2e8cc54 100644
+--- a/fs/ext4/ialloc.c
++++ b/fs/ext4/ialloc.c
+@@ -756,10 +756,10 @@ int ext4_mark_inode_used(struct super_block *sb, int ino)
+ struct ext4_group_desc *gdp;
+ ext4_group_t group;
+ int bit;
+- int err = -EFSCORRUPTED;
++ int err;
+
+ if (ino < EXT4_FIRST_INO(sb) || ino > max_ino)
+- goto out;
++ return -EFSCORRUPTED;
+
+ group = (ino - 1) / EXT4_INODES_PER_GROUP(sb);
+ bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb);
+@@ -862,6 +862,7 @@ int ext4_mark_inode_used(struct super_block *sb, int ino)
+ err = ext4_handle_dirty_metadata(NULL, NULL, group_desc_bh);
+ sync_dirty_buffer(group_desc_bh);
+ out:
++ brelse(inode_bitmap_bh);
+ return err;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 02143a14ffa183e100a0856e53a49ce76fdac8a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Aug 2024 21:22:30 +0800
+Subject: ext4: avoid negative min_clusters in find_group_orlov()
+
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+
+[ Upstream commit bb0a12c3439b10d88412fd3102df5b9a6e3cd6dc ]
+
+min_clusters is signed integer and will be converted to unsigned
+integer when compared with unsigned number stats.free_clusters.
+If min_clusters is negative, it will be converted to a huge unsigned
+value in which case all groups may not meet the actual desired free
+clusters.
+Set negative min_clusters to 0 to avoid unexpected behavior.
+
+Fixes: ac27a0ec112a ("[PATCH] ext4: initial copy of files from ext3")
+Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
+Link: https://patch.msgid.link/20240820132234.2759926-4-shikemeng@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/ialloc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
+index a00c91aa755c4..5841686e80b3a 100644
+--- a/fs/ext4/ialloc.c
++++ b/fs/ext4/ialloc.c
+@@ -515,6 +515,8 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
+ if (min_inodes < 1)
+ min_inodes = 1;
+ min_clusters = avefreec - EXT4_CLUSTERS_PER_GROUP(sb)*flex_size / 4;
++ if (min_clusters < 0)
++ min_clusters = 0;
+
+ /*
+ * Start looking in the flex group where we last allocated an
+--
+2.43.0
+
--- /dev/null
+From 27034d3296e67775e7d0e04394fa0e951b381bf1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Aug 2024 12:23:24 -0300
+Subject: ext4: avoid OOB when system.data xattr changes underneath the
+ filesystem
+
+From: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
+
+[ Upstream commit c6b72f5d82b1017bad80f9ebf502832fc321d796 ]
+
+When looking up for an entry in an inlined directory, if e_value_offs is
+changed underneath the filesystem by some change in the block device, it
+will lead to an out-of-bounds access that KASAN detects as an UAF.
+
+EXT4-fs (loop0): mounted filesystem 00000000-0000-0000-0000-000000000000 r/w without journal. Quota mode: none.
+loop0: detected capacity change from 2048 to 2047
+==================================================================
+BUG: KASAN: use-after-free in ext4_search_dir+0xf2/0x1c0 fs/ext4/namei.c:1500
+Read of size 1 at addr ffff88803e91130f by task syz-executor269/5103
+
+CPU: 0 UID: 0 PID: 5103 Comm: syz-executor269 Not tainted 6.11.0-rc4-syzkaller #0
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:93 [inline]
+ dump_stack_lvl+0x241/0x360 lib/dump_stack.c:119
+ print_address_description mm/kasan/report.c:377 [inline]
+ print_report+0x169/0x550 mm/kasan/report.c:488
+ kasan_report+0x143/0x180 mm/kasan/report.c:601
+ ext4_search_dir+0xf2/0x1c0 fs/ext4/namei.c:1500
+ ext4_find_inline_entry+0x4be/0x5e0 fs/ext4/inline.c:1697
+ __ext4_find_entry+0x2b4/0x1b30 fs/ext4/namei.c:1573
+ ext4_lookup_entry fs/ext4/namei.c:1727 [inline]
+ ext4_lookup+0x15f/0x750 fs/ext4/namei.c:1795
+ lookup_one_qstr_excl+0x11f/0x260 fs/namei.c:1633
+ filename_create+0x297/0x540 fs/namei.c:3980
+ do_symlinkat+0xf9/0x3a0 fs/namei.c:4587
+ __do_sys_symlinkat fs/namei.c:4610 [inline]
+ __se_sys_symlinkat fs/namei.c:4607 [inline]
+ __x64_sys_symlinkat+0x95/0xb0 fs/namei.c:4607
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7f3e73ced469
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 21 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007fff4d40c258 EFLAGS: 00000246 ORIG_RAX: 000000000000010a
+RAX: ffffffffffffffda RBX: 0032656c69662f2e RCX: 00007f3e73ced469
+RDX: 0000000020000200 RSI: 00000000ffffff9c RDI: 00000000200001c0
+RBP: 0000000000000000 R08: 00007fff4d40c290 R09: 00007fff4d40c290
+R10: 0023706f6f6c2f76 R11: 0000000000000246 R12: 00007fff4d40c27c
+R13: 0000000000000003 R14: 431bde82d7b634db R15: 00007fff4d40c2b0
+ </TASK>
+
+Calling ext4_xattr_ibody_find right after reading the inode with
+ext4_get_inode_loc will lead to a check of the validity of the xattrs,
+avoiding this problem.
+
+Reported-by: syzbot+0c2508114d912a54ee79@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=0c2508114d912a54ee79
+Fixes: e8e948e7802a ("ext4: let ext4_find_entry handle inline data")
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
+Link: https://patch.msgid.link/20240821152324.3621860-5-cascardo@igalia.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/inline.c | 31 +++++++++++++++++++++----------
+ 1 file changed, 21 insertions(+), 10 deletions(-)
+
+diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
+index 9e42c3b18458a..df74916db981c 100644
+--- a/fs/ext4/inline.c
++++ b/fs/ext4/inline.c
+@@ -1671,25 +1671,36 @@ struct buffer_head *ext4_find_inline_entry(struct inode *dir,
+ struct ext4_dir_entry_2 **res_dir,
+ int *has_inline_data)
+ {
++ struct ext4_xattr_ibody_find is = {
++ .s = { .not_found = -ENODATA, },
++ };
++ struct ext4_xattr_info i = {
++ .name_index = EXT4_XATTR_INDEX_SYSTEM,
++ .name = EXT4_XATTR_SYSTEM_DATA,
++ };
+ int ret;
+- struct ext4_iloc iloc;
+ void *inline_start;
+ int inline_size;
+
+- ret = ext4_get_inode_loc(dir, &iloc);
++ ret = ext4_get_inode_loc(dir, &is.iloc);
+ if (ret)
+ return ERR_PTR(ret);
+
+ down_read(&EXT4_I(dir)->xattr_sem);
++
++ ret = ext4_xattr_ibody_find(dir, &i, &is);
++ if (ret)
++ goto out;
++
+ if (!ext4_has_inline_data(dir)) {
+ *has_inline_data = 0;
+ goto out;
+ }
+
+- inline_start = (void *)ext4_raw_inode(&iloc)->i_block +
++ inline_start = (void *)ext4_raw_inode(&is.iloc)->i_block +
+ EXT4_INLINE_DOTDOT_SIZE;
+ inline_size = EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DOTDOT_SIZE;
+- ret = ext4_search_dir(iloc.bh, inline_start, inline_size,
++ ret = ext4_search_dir(is.iloc.bh, inline_start, inline_size,
+ dir, fname, 0, res_dir);
+ if (ret == 1)
+ goto out_find;
+@@ -1699,23 +1710,23 @@ struct buffer_head *ext4_find_inline_entry(struct inode *dir,
+ if (ext4_get_inline_size(dir) == EXT4_MIN_INLINE_DATA_SIZE)
+ goto out;
+
+- inline_start = ext4_get_inline_xattr_pos(dir, &iloc);
++ inline_start = ext4_get_inline_xattr_pos(dir, &is.iloc);
+ inline_size = ext4_get_inline_size(dir) - EXT4_MIN_INLINE_DATA_SIZE;
+
+- ret = ext4_search_dir(iloc.bh, inline_start, inline_size,
++ ret = ext4_search_dir(is.iloc.bh, inline_start, inline_size,
+ dir, fname, 0, res_dir);
+ if (ret == 1)
+ goto out_find;
+
+ out:
+- brelse(iloc.bh);
++ brelse(is.iloc.bh);
+ if (ret < 0)
+- iloc.bh = ERR_PTR(ret);
++ is.iloc.bh = ERR_PTR(ret);
+ else
+- iloc.bh = NULL;
++ is.iloc.bh = NULL;
+ out_find:
+ up_read(&EXT4_I(dir)->xattr_sem);
+- return iloc.bh;
++ return is.iloc.bh;
+ }
+
+ int ext4_delete_inline_entry(handle_t *handle,
+--
+2.43.0
+
--- /dev/null
+From 7b96ba6845ea51e6a901658ff884310e951f262d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Aug 2024 21:22:29 +0800
+Subject: ext4: avoid potential buffer_head leak in __ext4_new_inode()
+
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+
+[ Upstream commit 227d31b9214d1b9513383cf6c7180628d4b3b61f ]
+
+If a group is marked EXT4_GROUP_INFO_IBITMAP_CORRUPT after it's inode
+bitmap buffer_head was successfully verified, then __ext4_new_inode()
+will get a valid inode_bitmap_bh of a corrupted group from
+ext4_read_inode_bitmap() in which case inode_bitmap_bh misses a release.
+Hnadle "IS_ERR(inode_bitmap_bh)" and group corruption separately like
+how ext4_free_inode() does to avoid buffer_head leak.
+
+Fixes: 9008a58e5dce ("ext4: make the bitmap read routines return real error codes")
+Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
+Link: https://patch.msgid.link/20240820132234.2759926-3-shikemeng@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/ialloc.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
+index 4478ba2e8cc54..a00c91aa755c4 100644
+--- a/fs/ext4/ialloc.c
++++ b/fs/ext4/ialloc.c
+@@ -1056,12 +1056,13 @@ struct inode *__ext4_new_inode(struct user_namespace *mnt_userns,
+ brelse(inode_bitmap_bh);
+ inode_bitmap_bh = ext4_read_inode_bitmap(sb, group);
+ /* Skip groups with suspicious inode tables */
+- if (((!(sbi->s_mount_state & EXT4_FC_REPLAY))
+- && EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) ||
+- IS_ERR(inode_bitmap_bh)) {
++ if (IS_ERR(inode_bitmap_bh)) {
+ inode_bitmap_bh = NULL;
+ goto next_group;
+ }
++ if (!(sbi->s_mount_state & EXT4_FC_REPLAY) &&
++ EXT4_MB_GRP_IBITMAP_CORRUPT(grp))
++ goto next_group;
+
+ repeat_in_this_group:
+ ret2 = find_inode_bit(sb, group, inode_bitmap_bh, &ino);
+--
+2.43.0
+
--- /dev/null
+From f87d80cd9f073b3f001fa747e3284dedb95e8880 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Aug 2024 16:55:10 +0800
+Subject: ext4: clear EXT4_GROUP_INFO_WAS_TRIMMED_BIT even mount with discard
+
+From: yangerkun <yangerkun@huawei.com>
+
+[ Upstream commit 20cee68f5b44fdc2942d20f3172a262ec247b117 ]
+
+Commit 3d56b8d2c74c ("ext4: Speed up FITRIM by recording flags in
+ext4_group_info") speed up fstrim by skipping trim trimmed group. We
+also has the chance to clear trimmed once there exists some block free
+for this group(mount without discard), and the next trim for this group
+will work well too.
+
+For mount with discard, we will issue dicard when we free blocks, so
+leave trimmed flag keep alive to skip useless trim trigger from
+userspace seems reasonable. But for some case like ext4 build on
+dm-thinpool(ext4 blocksize 4K, pool blocksize 128K), discard from ext4
+maybe unaligned for dm thinpool, and thinpool will just finish this
+discard(see process_discard_bio when begein equals to end) without
+actually process discard. For this case, trim from userspace can really
+help us to free some thinpool block.
+
+So convert to clear trimmed flag for all case no matter mounted with
+discard or not.
+
+Fixes: 3d56b8d2c74c ("ext4: Speed up FITRIM by recording flags in ext4_group_info")
+Signed-off-by: yangerkun <yangerkun@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://patch.msgid.link/20240817085510.2084444-1-yangerkun@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/mballoc.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index a48c9cc5aa6e8..6b7d69037b836 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -3721,11 +3721,8 @@ static void ext4_free_data_in_buddy(struct super_block *sb,
+ /*
+ * Clear the trimmed flag for the group so that the next
+ * ext4_trim_fs can trim it.
+- * If the volume is mounted with -o discard, online discard
+- * is supported and the free blocks will be trimmed online.
+ */
+- if (!test_opt(sb, DISCARD))
+- EXT4_MB_GRP_CLEAR_TRIMMED(db);
++ EXT4_MB_GRP_CLEAR_TRIMMED(db);
+
+ if (!db->bb_free_root.rb_node) {
+ /* No more items in the per group rb tree
+@@ -6127,8 +6124,9 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode,
+ " group:%u block:%d count:%lu failed"
+ " with %d", block_group, bit, count,
+ err);
+- } else
+- EXT4_MB_GRP_CLEAR_TRIMMED(e4b.bd_info);
++ }
++
++ EXT4_MB_GRP_CLEAR_TRIMMED(e4b.bd_info);
+
+ ext4_lock_group(sb, block_group);
+ mb_clear_bits(bitmap_bh->b_data, bit, count_clusters);
+--
+2.43.0
+
--- /dev/null
+From deb4af7e50e79d9d1399ed27a88244522b1d8e03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Aug 2024 12:23:22 -0300
+Subject: ext4: return error on ext4_find_inline_entry
+
+From: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
+
+[ Upstream commit 4d231b91a944f3cab355fce65af5871fb5d7735b ]
+
+In case of errors when reading an inode from disk or traversing inline
+directory entries, return an error-encoded ERR_PTR instead of returning
+NULL. ext4_find_inline_entry only caller, __ext4_find_entry already returns
+such encoded errors.
+
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
+Link: https://patch.msgid.link/20240821152324.3621860-3-cascardo@igalia.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: c6b72f5d82b1 ("ext4: avoid OOB when system.data xattr changes underneath the filesystem")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/inline.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
+index bc7f6417888dc..9e42c3b18458a 100644
+--- a/fs/ext4/inline.c
++++ b/fs/ext4/inline.c
+@@ -1676,8 +1676,9 @@ struct buffer_head *ext4_find_inline_entry(struct inode *dir,
+ void *inline_start;
+ int inline_size;
+
+- if (ext4_get_inode_loc(dir, &iloc))
+- return NULL;
++ ret = ext4_get_inode_loc(dir, &iloc);
++ if (ret)
++ return ERR_PTR(ret);
+
+ down_read(&EXT4_I(dir)->xattr_sem);
+ if (!ext4_has_inline_data(dir)) {
+@@ -1708,7 +1709,10 @@ struct buffer_head *ext4_find_inline_entry(struct inode *dir,
+
+ out:
+ brelse(iloc.bh);
+- iloc.bh = NULL;
++ if (ret < 0)
++ iloc.bh = ERR_PTR(ret);
++ else
++ iloc.bh = NULL;
+ out_find:
+ up_read(&EXT4_I(dir)->xattr_sem);
+ return iloc.bh;
+--
+2.43.0
+
--- /dev/null
+From 87841cc61f971f2797c965e8bac60753610c0b58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Nov 2023 14:25:54 +0800
+Subject: f2fs: clean up w/ dotdot_name
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit ff6584ac2c4b4ee8e1fca20bffaaa387d8fe2974 ]
+
+Just cleanup, no logic changes.
+
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: 884ee6dc85b9 ("f2fs: get rid of online repaire on corrupted directory")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/namei.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
+index 80bc386ec6980..966578587bbe3 100644
+--- a/fs/f2fs/namei.c
++++ b/fs/f2fs/namei.c
+@@ -454,7 +454,6 @@ static int __recover_dot_dentries(struct inode *dir, nid_t pino)
+ {
+ struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
+ struct qstr dot = QSTR_INIT(".", 1);
+- struct qstr dotdot = QSTR_INIT("..", 2);
+ struct f2fs_dir_entry *de;
+ struct page *page;
+ int err = 0;
+@@ -492,13 +491,13 @@ static int __recover_dot_dentries(struct inode *dir, nid_t pino)
+ goto out;
+ }
+
+- de = f2fs_find_entry(dir, &dotdot, &page);
++ de = f2fs_find_entry(dir, &dotdot_name, &page);
+ if (de)
+ f2fs_put_page(page, 0);
+ else if (IS_ERR(page))
+ err = PTR_ERR(page);
+ else
+- err = f2fs_do_add_link(dir, &dotdot, NULL, pino, S_IFDIR);
++ err = f2fs_do_add_link(dir, &dotdot_name, NULL, pino, S_IFDIR);
+ out:
+ if (!err)
+ clear_inode_flag(dir, FI_INLINE_DOTS);
+--
+2.43.0
+
--- /dev/null
+From 9917ffcc7b64b331fc69060c09edfffbd18badcd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Jul 2023 21:50:45 +0800
+Subject: f2fs: fix to update i_ctime in __f2fs_setxattr()
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 8874ad7dae8d91d24cc87c545c0073b3b2da5688 ]
+
+generic/728 - output mismatch (see /media/fstests/results//generic/728.out.bad)
+ --- tests/generic/728.out 2023-07-19 07:10:48.362711407 +0000
+ +++ /media/fstests/results//generic/728.out.bad 2023-07-19 08:39:57.000000000 +0000
+ QA output created by 728
+ +Expected ctime to change after setxattr.
+ +Expected ctime to change after removexattr.
+ Silence is golden
+ ...
+ (Run 'diff -u /media/fstests/tests/generic/728.out /media/fstests/results//generic/728.out.bad' to see the entire diff)
+generic/729 1s
+
+It needs to update i_ctime after {set,remove}xattr, fix it.
+
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: aaf8c0b9ae04 ("f2fs: reduce expensive checkpoint trigger frequency")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/xattr.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
+index 1a18936bc583b..4f2069bf2b4bc 100644
+--- a/fs/f2fs/xattr.c
++++ b/fs/f2fs/xattr.c
+@@ -760,17 +760,17 @@ static int __f2fs_setxattr(struct inode *inode, int index,
+ if (index == F2FS_XATTR_INDEX_ENCRYPTION &&
+ !strcmp(name, F2FS_XATTR_NAME_ENCRYPTION_CONTEXT))
+ f2fs_set_encrypted_inode(inode);
+- f2fs_mark_inode_dirty_sync(inode, true);
+ if (!error && S_ISDIR(inode->i_mode))
+ set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_CP);
+
+ same:
+ if (is_inode_flag_set(inode, FI_ACL_MODE)) {
+ inode->i_mode = F2FS_I(inode)->i_acl_mode;
+- inode->i_ctime = current_time(inode);
+ clear_inode_flag(inode, FI_ACL_MODE);
+ }
+
++ inode->i_ctime = current_time(inode);
++ f2fs_mark_inode_dirty_sync(inode, true);
+ exit:
+ kfree(base_addr);
+ return error;
+--
+2.43.0
+
--- /dev/null
+From 18a1b587e875c99e3506173cb991b2565082c340 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Aug 2024 22:12:42 +0800
+Subject: f2fs: fix to wait page writeback before setting gcing flag
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit a4d7f2b3238fd5f76b9e6434a0bd5d2e29049cff ]
+
+Soft IRQ Thread
+- f2fs_write_end_io
+ - f2fs_defragment_range
+ - set_page_private_gcing
+ - type = WB_DATA_TYPE(page, false);
+ : assign type w/ F2FS_WB_CP_DATA
+ due to page_private_gcing() is true
+ - dec_page_count() w/ wrong type
+ - end_page_writeback()
+
+Value of F2FS_WB_CP_DATA reference count may become negative under above
+race condition, the root cause is we missed to wait page writeback before
+setting gcing page private flag, let's fix it.
+
+Fixes: 2d1fe8a86bf5 ("f2fs: fix to tag gcing flag on page during file defragment")
+Fixes: 4961acdd65c9 ("f2fs: fix to tag gcing flag on page during block migration")
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 2f2cd520f55d6..0427994c9b50a 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -2683,6 +2683,8 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
+ goto clear_out;
+ }
+
++ f2fs_wait_on_page_writeback(page, DATA, true, true);
++
+ set_page_dirty(page);
+ set_page_private_gcing(page);
+ f2fs_put_page(page, 1);
+@@ -4015,6 +4017,8 @@ static int redirty_blocks(struct inode *inode, pgoff_t page_idx, int len)
+ /* It will never fail, when page has pinned above */
+ f2fs_bug_on(F2FS_I_SB(inode), !page);
+
++ f2fs_wait_on_page_writeback(page, DATA, true, true);
++
+ set_page_dirty(page);
+ set_page_private_gcing(page);
+ f2fs_put_page(page, 1);
+--
+2.43.0
+
--- /dev/null
+From 34732699be6bb983c9d6abc1a4cbc0e0f55bee1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Sep 2022 11:07:49 +0900
+Subject: f2fs: fix typo
+
+From: Yonggil Song <yonggil.song@samsung.com>
+
+[ Upstream commit d382e36970ecf8242921400db2afde15fb6ed49e ]
+
+Fix typo in f2fs.h
+Detected by Jaeyoon Choi
+
+Signed-off-by: Yonggil Song <yonggil.song@samsung.com>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: aaf8c0b9ae04 ("f2fs: reduce expensive checkpoint trigger frequency")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/f2fs.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index e49fca9daf2d3..25f879ed599a5 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -261,7 +261,7 @@ enum {
+ ORPHAN_INO, /* for orphan ino list */
+ APPEND_INO, /* for append ino list */
+ UPDATE_INO, /* for update ino list */
+- TRANS_DIR_INO, /* for trasactions dir ino list */
++ TRANS_DIR_INO, /* for transactions dir ino list */
+ FLUSH_INO, /* for multiple device flushing */
+ MAX_INO_ENTRY, /* max. list */
+ };
+--
+2.43.0
+
--- /dev/null
+From a6aee4bdde76fa3ca7844a55694fc8b29bee9a49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Sep 2024 14:27:24 +0800
+Subject: f2fs: get rid of online repaire on corrupted directory
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 884ee6dc85b959bc152f15bca80c30f06069e6c4 ]
+
+syzbot reports a f2fs bug as below:
+
+kernel BUG at fs/f2fs/inode.c:896!
+RIP: 0010:f2fs_evict_inode+0x1598/0x15c0 fs/f2fs/inode.c:896
+Call Trace:
+ evict+0x532/0x950 fs/inode.c:704
+ dispose_list fs/inode.c:747 [inline]
+ evict_inodes+0x5f9/0x690 fs/inode.c:797
+ generic_shutdown_super+0x9d/0x2d0 fs/super.c:627
+ kill_block_super+0x44/0x90 fs/super.c:1696
+ kill_f2fs_super+0x344/0x690 fs/f2fs/super.c:4898
+ deactivate_locked_super+0xc4/0x130 fs/super.c:473
+ cleanup_mnt+0x41f/0x4b0 fs/namespace.c:1373
+ task_work_run+0x24f/0x310 kernel/task_work.c:228
+ ptrace_notify+0x2d2/0x380 kernel/signal.c:2402
+ ptrace_report_syscall include/linux/ptrace.h:415 [inline]
+ ptrace_report_syscall_exit include/linux/ptrace.h:477 [inline]
+ syscall_exit_work+0xc6/0x190 kernel/entry/common.c:173
+ syscall_exit_to_user_mode_prepare kernel/entry/common.c:200 [inline]
+ __syscall_exit_to_user_mode_work kernel/entry/common.c:205 [inline]
+ syscall_exit_to_user_mode+0x279/0x370 kernel/entry/common.c:218
+ do_syscall_64+0x100/0x230 arch/x86/entry/common.c:89
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0010:f2fs_evict_inode+0x1598/0x15c0 fs/f2fs/inode.c:896
+
+Online repaire on corrupted directory in f2fs_lookup() can generate
+dirty data/meta while racing w/ readonly remount, it may leave dirty
+inode after filesystem becomes readonly, however, checkpoint() will
+skips flushing dirty inode in a state of readonly mode, result in
+above panic.
+
+Let's get rid of online repaire in f2fs_lookup(), and leave the work
+to fsck.f2fs.
+
+Fixes: 510022a85839 ("f2fs: add F2FS_INLINE_DOTS to recover missing dot dentries")
+Reported-by: syzbot+ebea2790904673d7c618@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/000000000000a7b20f061ff2d56a@google.com
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/f2fs.h | 11 -------
+ fs/f2fs/namei.c | 68 -----------------------------------------
+ include/linux/f2fs_fs.h | 2 +-
+ 3 files changed, 1 insertion(+), 80 deletions(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index f2c55a5afe67b..856a44da7977c 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -714,7 +714,6 @@ enum {
+ FI_FIRST_BLOCK_WRITTEN, /* indicate #0 data block was written */
+ FI_DROP_CACHE, /* drop dirty page cache */
+ FI_DATA_EXIST, /* indicate data exists */
+- FI_INLINE_DOTS, /* indicate inline dot dentries */
+ FI_SKIP_WRITES, /* should skip data page writeback */
+ FI_OPU_WRITE, /* used for opu per file */
+ FI_DIRTY_FILE, /* indicate regular/symlink has dirty pages */
+@@ -2841,7 +2840,6 @@ static inline void __mark_inode_dirty_flag(struct inode *inode,
+ return;
+ fallthrough;
+ case FI_DATA_EXIST:
+- case FI_INLINE_DOTS:
+ case FI_PIN_FILE:
+ case FI_COMPRESS_RELEASED:
+ f2fs_mark_inode_dirty_sync(inode, true);
+@@ -2959,8 +2957,6 @@ static inline void get_inline_info(struct inode *inode, struct f2fs_inode *ri)
+ set_bit(FI_INLINE_DENTRY, fi->flags);
+ if (ri->i_inline & F2FS_DATA_EXIST)
+ set_bit(FI_DATA_EXIST, fi->flags);
+- if (ri->i_inline & F2FS_INLINE_DOTS)
+- set_bit(FI_INLINE_DOTS, fi->flags);
+ if (ri->i_inline & F2FS_EXTRA_ATTR)
+ set_bit(FI_EXTRA_ATTR, fi->flags);
+ if (ri->i_inline & F2FS_PIN_FILE)
+@@ -2981,8 +2977,6 @@ static inline void set_raw_inline(struct inode *inode, struct f2fs_inode *ri)
+ ri->i_inline |= F2FS_INLINE_DENTRY;
+ if (is_inode_flag_set(inode, FI_DATA_EXIST))
+ ri->i_inline |= F2FS_DATA_EXIST;
+- if (is_inode_flag_set(inode, FI_INLINE_DOTS))
+- ri->i_inline |= F2FS_INLINE_DOTS;
+ if (is_inode_flag_set(inode, FI_EXTRA_ATTR))
+ ri->i_inline |= F2FS_EXTRA_ATTR;
+ if (is_inode_flag_set(inode, FI_PIN_FILE))
+@@ -3065,11 +3059,6 @@ static inline int f2fs_exist_data(struct inode *inode)
+ return is_inode_flag_set(inode, FI_DATA_EXIST);
+ }
+
+-static inline int f2fs_has_inline_dots(struct inode *inode)
+-{
+- return is_inode_flag_set(inode, FI_INLINE_DOTS);
+-}
+-
+ static inline int f2fs_is_mmap_file(struct inode *inode)
+ {
+ return is_inode_flag_set(inode, FI_MMAP_FILE);
+diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
+index 966578587bbe3..b70ac99267728 100644
+--- a/fs/f2fs/namei.c
++++ b/fs/f2fs/namei.c
+@@ -450,62 +450,6 @@ struct dentry *f2fs_get_parent(struct dentry *child)
+ return d_obtain_alias(f2fs_iget(child->d_sb, ino));
+ }
+
+-static int __recover_dot_dentries(struct inode *dir, nid_t pino)
+-{
+- struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
+- struct qstr dot = QSTR_INIT(".", 1);
+- struct f2fs_dir_entry *de;
+- struct page *page;
+- int err = 0;
+-
+- if (f2fs_readonly(sbi->sb)) {
+- f2fs_info(sbi, "skip recovering inline_dots inode (ino:%lu, pino:%u) in readonly mountpoint",
+- dir->i_ino, pino);
+- return 0;
+- }
+-
+- if (!S_ISDIR(dir->i_mode)) {
+- f2fs_err(sbi, "inconsistent inode status, skip recovering inline_dots inode (ino:%lu, i_mode:%u, pino:%u)",
+- dir->i_ino, dir->i_mode, pino);
+- set_sbi_flag(sbi, SBI_NEED_FSCK);
+- return -ENOTDIR;
+- }
+-
+- err = f2fs_dquot_initialize(dir);
+- if (err)
+- return err;
+-
+- f2fs_balance_fs(sbi, true);
+-
+- f2fs_lock_op(sbi);
+-
+- de = f2fs_find_entry(dir, &dot, &page);
+- if (de) {
+- f2fs_put_page(page, 0);
+- } else if (IS_ERR(page)) {
+- err = PTR_ERR(page);
+- goto out;
+- } else {
+- err = f2fs_do_add_link(dir, &dot, NULL, dir->i_ino, S_IFDIR);
+- if (err)
+- goto out;
+- }
+-
+- de = f2fs_find_entry(dir, &dotdot_name, &page);
+- if (de)
+- f2fs_put_page(page, 0);
+- else if (IS_ERR(page))
+- err = PTR_ERR(page);
+- else
+- err = f2fs_do_add_link(dir, &dotdot_name, NULL, pino, S_IFDIR);
+-out:
+- if (!err)
+- clear_inode_flag(dir, FI_INLINE_DOTS);
+-
+- f2fs_unlock_op(sbi);
+- return err;
+-}
+-
+ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
+ unsigned int flags)
+ {
+@@ -515,7 +459,6 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
+ struct dentry *new;
+ nid_t ino = -1;
+ int err = 0;
+- unsigned int root_ino = F2FS_ROOT_INO(F2FS_I_SB(dir));
+ struct f2fs_filename fname;
+
+ trace_f2fs_lookup_start(dir, dentry, flags);
+@@ -552,17 +495,6 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
+ goto out;
+ }
+
+- if ((dir->i_ino == root_ino) && f2fs_has_inline_dots(dir)) {
+- err = __recover_dot_dentries(dir, root_ino);
+- if (err)
+- goto out_iput;
+- }
+-
+- if (f2fs_has_inline_dots(inode)) {
+- err = __recover_dot_dentries(inode, dir->i_ino);
+- if (err)
+- goto out_iput;
+- }
+ if (IS_ENCRYPTED(dir) &&
+ (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
+ !fscrypt_has_permitted_context(dir, inode)) {
+diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
+index d445150c5350f..9b972b58e198c 100644
+--- a/include/linux/f2fs_fs.h
++++ b/include/linux/f2fs_fs.h
+@@ -227,7 +227,7 @@ struct f2fs_extent {
+ #define F2FS_INLINE_DATA 0x02 /* file inline data flag */
+ #define F2FS_INLINE_DENTRY 0x04 /* file inline dentry flag */
+ #define F2FS_DATA_EXIST 0x08 /* file inline data exist flag */
+-#define F2FS_INLINE_DOTS 0x10 /* file having implicit dot dentries */
++#define F2FS_INLINE_DOTS 0x10 /* file having implicit dot dentries (obsolete) */
+ #define F2FS_EXTRA_ATTR 0x20 /* file having extra attribute */
+ #define F2FS_PIN_FILE 0x40 /* file should not be gced */
+ #define F2FS_COMPRESS_RELEASED 0x80 /* file released compressed blocks */
+--
+2.43.0
+
--- /dev/null
+From cde0ffbfc56f367e88b034acea980dd0e4ae3cfe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Feb 2022 15:19:46 +0800
+Subject: f2fs: introduce F2FS_IPU_HONOR_OPU_WRITE ipu policy
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 1018a5463a063715365784704c4e8cdf2eec4b04 ]
+
+Once F2FS_IPU_FORCE policy is enabled in some cases:
+a) f2fs forces to use F2FS_IPU_FORCE in a small-sized volume
+b) user sets F2FS_IPU_FORCE policy via sysfs
+
+Then we may fail to defragment file due to IPU policy check, it doesn't
+make sense, let's introduce a new IPU policy to allow OPU during file
+defragmentation.
+
+In small-sized volume, let's enable F2FS_IPU_HONOR_OPU_WRITE policy
+by default.
+
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: 884ee6dc85b9 ("f2fs: get rid of online repaire on corrupted directory")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/ABI/testing/sysfs-fs-f2fs | 3 ++-
+ fs/f2fs/data.c | 18 +++++++++++++-----
+ fs/f2fs/f2fs.h | 3 ++-
+ fs/f2fs/file.c | 18 +++++++++++-------
+ fs/f2fs/segment.h | 5 ++++-
+ fs/f2fs/super.c | 3 ++-
+ 6 files changed, 34 insertions(+), 16 deletions(-)
+
+diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
+index 48d41b6696270..89dec1f3ea6d9 100644
+--- a/Documentation/ABI/testing/sysfs-fs-f2fs
++++ b/Documentation/ABI/testing/sysfs-fs-f2fs
+@@ -55,8 +55,9 @@ Description: Controls the in-place-update policy.
+ 0x04 F2FS_IPU_UTIL
+ 0x08 F2FS_IPU_SSR_UTIL
+ 0x10 F2FS_IPU_FSYNC
+- 0x20 F2FS_IPU_ASYNC,
++ 0x20 F2FS_IPU_ASYNC
+ 0x40 F2FS_IPU_NOCACHE
++ 0x80 F2FS_IPU_HONOR_OPU_WRITE
+ ==== =================
+
+ Refer segment.h for details.
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index fa86eaf1d6393..3f8dae229d422 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -2567,6 +2567,9 @@ static inline bool check_inplace_update_policy(struct inode *inode,
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ unsigned int policy = SM_I(sbi)->ipu_policy;
+
++ if (policy & (0x1 << F2FS_IPU_HONOR_OPU_WRITE) &&
++ is_inode_flag_set(inode, FI_OPU_WRITE))
++ return false;
+ if (policy & (0x1 << F2FS_IPU_FORCE))
+ return true;
+ if (policy & (0x1 << F2FS_IPU_SSR) && f2fs_need_SSR(sbi))
+@@ -2637,6 +2640,9 @@ bool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio)
+ if (is_inode_flag_set(inode, FI_ALIGNED_WRITE))
+ return true;
+
++ if (is_inode_flag_set(inode, FI_OPU_WRITE))
++ return true;
++
+ if (fio) {
+ if (page_private_gcing(fio->page))
+ return true;
+@@ -3263,8 +3269,8 @@ static int __f2fs_write_data_pages(struct address_space *mapping,
+ f2fs_available_free_memory(sbi, DIRTY_DENTS))
+ goto skip_write;
+
+- /* skip writing during file defragment */
+- if (is_inode_flag_set(inode, FI_DO_DEFRAG))
++ /* skip writing in file defragment preparing stage */
++ if (is_inode_flag_set(inode, FI_SKIP_WRITES))
+ goto skip_write;
+
+ trace_f2fs_writepages(mapping->host, wbc, DATA);
+@@ -3998,6 +4004,7 @@ static int f2fs_migrate_blocks(struct inode *inode, block_t start_blk,
+ filemap_invalidate_lock(inode->i_mapping);
+
+ set_inode_flag(inode, FI_ALIGNED_WRITE);
++ set_inode_flag(inode, FI_OPU_WRITE);
+
+ for (; secidx < end_sec; secidx++) {
+ down_write(&sbi->pin_sem);
+@@ -4006,7 +4013,7 @@ static int f2fs_migrate_blocks(struct inode *inode, block_t start_blk,
+ f2fs_allocate_new_section(sbi, CURSEG_COLD_DATA_PINNED, false);
+ f2fs_unlock_op(sbi);
+
+- set_inode_flag(inode, FI_DO_DEFRAG);
++ set_inode_flag(inode, FI_SKIP_WRITES);
+
+ for (blkofs = 0; blkofs < blk_per_sec; blkofs++) {
+ struct page *page;
+@@ -4023,7 +4030,7 @@ static int f2fs_migrate_blocks(struct inode *inode, block_t start_blk,
+ f2fs_put_page(page, 1);
+ }
+
+- clear_inode_flag(inode, FI_DO_DEFRAG);
++ clear_inode_flag(inode, FI_SKIP_WRITES);
+
+ ret = filemap_fdatawrite(inode->i_mapping);
+
+@@ -4034,7 +4041,8 @@ static int f2fs_migrate_blocks(struct inode *inode, block_t start_blk,
+ }
+
+ done:
+- clear_inode_flag(inode, FI_DO_DEFRAG);
++ clear_inode_flag(inode, FI_SKIP_WRITES);
++ clear_inode_flag(inode, FI_OPU_WRITE);
+ clear_inode_flag(inode, FI_ALIGNED_WRITE);
+
+ filemap_invalidate_unlock(inode->i_mapping);
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index cd3439ea6d727..f2c55a5afe67b 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -715,7 +715,8 @@ enum {
+ FI_DROP_CACHE, /* drop dirty page cache */
+ FI_DATA_EXIST, /* indicate data exists */
+ FI_INLINE_DOTS, /* indicate inline dot dentries */
+- FI_DO_DEFRAG, /* indicate defragment is running */
++ FI_SKIP_WRITES, /* should skip data page writeback */
++ FI_OPU_WRITE, /* used for opu per file */
+ FI_DIRTY_FILE, /* indicate regular/symlink has dirty pages */
+ FI_NO_PREALLOC, /* indicate skipped preallocated blocks */
+ FI_HOT_DATA, /* indicate file is hot */
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 0427994c9b50a..ee20d79bd93e4 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -2579,10 +2579,6 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
+ bool fragmented = false;
+ int err;
+
+- /* if in-place-update policy is enabled, don't waste time here */
+- if (f2fs_should_update_inplace(inode, NULL))
+- return -EINVAL;
+-
+ pg_start = range->start >> PAGE_SHIFT;
+ pg_end = (range->start + range->len) >> PAGE_SHIFT;
+
+@@ -2590,6 +2586,13 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
+
+ inode_lock(inode);
+
++ /* if in-place-update policy is enabled, don't waste time here */
++ set_inode_flag(inode, FI_OPU_WRITE);
++ if (f2fs_should_update_inplace(inode, NULL)) {
++ err = -EINVAL;
++ goto out;
++ }
++
+ /* writeback all dirty pages in the range */
+ err = filemap_write_and_wait_range(inode->i_mapping, range->start,
+ range->start + range->len - 1);
+@@ -2671,7 +2674,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
+ goto check;
+ }
+
+- set_inode_flag(inode, FI_DO_DEFRAG);
++ set_inode_flag(inode, FI_SKIP_WRITES);
+
+ idx = map.m_lblk;
+ while (idx < map.m_lblk + map.m_len && cnt < blk_per_seg) {
+@@ -2699,15 +2702,16 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
+ if (map.m_lblk < pg_end && cnt < blk_per_seg)
+ goto do_map;
+
+- clear_inode_flag(inode, FI_DO_DEFRAG);
++ clear_inode_flag(inode, FI_SKIP_WRITES);
+
+ err = filemap_fdatawrite(inode->i_mapping);
+ if (err)
+ goto out;
+ }
+ clear_out:
+- clear_inode_flag(inode, FI_DO_DEFRAG);
++ clear_inode_flag(inode, FI_SKIP_WRITES);
+ out:
++ clear_inode_flag(inode, FI_OPU_WRITE);
+ inode_unlock(inode);
+ if (!err)
+ range->len = (u64)total << PAGE_SHIFT;
+diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
+index 04f448ddf49ea..2c1165e8f1283 100644
+--- a/fs/f2fs/segment.h
++++ b/fs/f2fs/segment.h
+@@ -665,7 +665,9 @@ static inline int utilization(struct f2fs_sb_info *sbi)
+ * pages over min_fsync_blocks. (=default option)
+ * F2FS_IPU_ASYNC - do IPU given by asynchronous write requests.
+ * F2FS_IPU_NOCACHE - disable IPU bio cache.
+- * F2FS_IPUT_DISABLE - disable IPU. (=default option in LFS mode)
++ * F2FS_IPU_HONOR_OPU_WRITE - use OPU write prior to IPU write if inode has
++ * FI_OPU_WRITE flag.
++ * F2FS_IPU_DISABLE - disable IPU. (=default option in LFS mode)
+ */
+ #define DEF_MIN_IPU_UTIL 70
+ #define DEF_MIN_FSYNC_BLOCKS 8
+@@ -681,6 +683,7 @@ enum {
+ F2FS_IPU_FSYNC,
+ F2FS_IPU_ASYNC,
+ F2FS_IPU_NOCACHE,
++ F2FS_IPU_HONOR_OPU_WRITE,
+ };
+
+ static inline unsigned int curseg_segno(struct f2fs_sb_info *sbi,
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 706d7adda3b22..17615eb833e0c 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -3971,7 +3971,8 @@ static void f2fs_tuning_parameters(struct f2fs_sb_info *sbi)
+ F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_REUSE;
+ if (f2fs_block_unit_discard(sbi))
+ sm_i->dcc_info->discard_granularity = 1;
+- sm_i->ipu_policy = 1 << F2FS_IPU_FORCE;
++ sm_i->ipu_policy = 1 << F2FS_IPU_FORCE |
++ 1 << F2FS_IPU_HONOR_OPU_WRITE;
+ }
+
+ sbi->readdir_ra = 1;
+--
+2.43.0
+
--- /dev/null
+From a3ce6660e6e4967c4c196721b1d3ce1b0ba1d3af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 May 2022 09:16:56 +0800
+Subject: f2fs: optimize error handling in redirty_blocks
+
+From: Jack Qiu <jack.qiu@huawei.com>
+
+[ Upstream commit a4a0e16dbf77582c4f58ab472229dd071b5c4260 ]
+
+Current error handling is at risk of page leaks. However, we dot't seek
+any failure scenarios, just use f2fs_bug_on.
+
+Signed-off-by: Jack Qiu <jack.qiu@huawei.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: a4d7f2b3238f ("f2fs: fix to wait page writeback before setting gcing flag")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/file.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 8551c3d3c2340..2f2cd520f55d6 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -4011,10 +4011,10 @@ static int redirty_blocks(struct inode *inode, pgoff_t page_idx, int len)
+
+ for (i = 0; i < page_len; i++, redirty_idx++) {
+ page = find_lock_page(mapping, redirty_idx);
+- if (!page) {
+- ret = -ENOMEM;
+- break;
+- }
++
++ /* It will never fail, when page has pinned above */
++ f2fs_bug_on(F2FS_I_SB(inode), !page);
++
+ set_page_dirty(page);
+ set_page_private_gcing(page);
+ f2fs_put_page(page, 1);
+--
+2.43.0
+
--- /dev/null
+From 289bffe6dc9c6eec4ebb74c451ffe9213de11183 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jun 2024 09:47:27 +0800
+Subject: f2fs: reduce expensive checkpoint trigger frequency
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit aaf8c0b9ae042494cb4585883b15c1332de77840 ]
+
+We may trigger high frequent checkpoint for below case:
+1. mkdir /mnt/dir1; set dir1 encrypted
+2. touch /mnt/file1; fsync /mnt/file1
+3. mkdir /mnt/dir2; set dir2 encrypted
+4. touch /mnt/file2; fsync /mnt/file2
+...
+
+Although, newly created dir and file are not related, due to
+commit bbf156f7afa7 ("f2fs: fix lost xattrs of directories"), we will
+trigger checkpoint whenever fsync() comes after a new encrypted dir
+created.
+
+In order to avoid such performance regression issue, let's record an
+entry including directory's ino in global cache whenever we update
+directory's xattr data, and then triggerring checkpoint() only if
+xattr metadata of target file's parent was updated.
+
+This patch updates to cover below no encryption case as well:
+1) parent is checkpointed
+2) set_xattr(dir) w/ new xnid
+3) create(file)
+4) fsync(file)
+
+Fixes: bbf156f7afa7 ("f2fs: fix lost xattrs of directories")
+Reported-by: wangzijie <wangzijie1@honor.com>
+Reported-by: Zhiguo Niu <zhiguo.niu@unisoc.com>
+Tested-by: Zhiguo Niu <zhiguo.niu@unisoc.com>
+Reported-by: Yunlei He <heyunlei@hihonor.com>
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/f2fs.h | 2 ++
+ fs/f2fs/file.c | 3 +++
+ fs/f2fs/xattr.c | 14 ++++++++++++--
+ include/trace/events/f2fs.h | 3 ++-
+ 4 files changed, 19 insertions(+), 3 deletions(-)
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 25f879ed599a5..cd3439ea6d727 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -262,6 +262,7 @@ enum {
+ APPEND_INO, /* for append ino list */
+ UPDATE_INO, /* for update ino list */
+ TRANS_DIR_INO, /* for transactions dir ino list */
++ XATTR_DIR_INO, /* for xattr updated dir ino list */
+ FLUSH_INO, /* for multiple device flushing */
+ MAX_INO_ENTRY, /* max. list */
+ };
+@@ -1124,6 +1125,7 @@ enum cp_reason_type {
+ CP_FASTBOOT_MODE,
+ CP_SPEC_LOG_NUM,
+ CP_RECOVER_DIR,
++ CP_XATTR_DIR,
+ };
+
+ enum iostat_type {
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index be9536815e50d..8551c3d3c2340 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -216,6 +216,9 @@ static inline enum cp_reason_type need_do_checkpoint(struct inode *inode)
+ f2fs_exist_written_data(sbi, F2FS_I(inode)->i_pino,
+ TRANS_DIR_INO))
+ cp_reason = CP_RECOVER_DIR;
++ else if (f2fs_exist_written_data(sbi, F2FS_I(inode)->i_pino,
++ XATTR_DIR_INO))
++ cp_reason = CP_XATTR_DIR;
+
+ return cp_reason;
+ }
+diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
+index ec019feab062e..6bc8efda406a6 100644
+--- a/fs/f2fs/xattr.c
++++ b/fs/f2fs/xattr.c
+@@ -631,6 +631,7 @@ static int __f2fs_setxattr(struct inode *inode, int index,
+ const char *name, const void *value, size_t size,
+ struct page *ipage, int flags)
+ {
++ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ struct f2fs_xattr_entry *here, *last;
+ void *base_addr, *last_base_addr;
+ int found, newsize;
+@@ -760,9 +761,18 @@ static int __f2fs_setxattr(struct inode *inode, int index,
+ if (index == F2FS_XATTR_INDEX_ENCRYPTION &&
+ !strcmp(name, F2FS_XATTR_NAME_ENCRYPTION_CONTEXT))
+ f2fs_set_encrypted_inode(inode);
+- if (S_ISDIR(inode->i_mode))
+- set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_CP);
+
++ if (!S_ISDIR(inode->i_mode))
++ goto same;
++ /*
++ * In restrict mode, fsync() always try to trigger checkpoint for all
++ * metadata consistency, in other mode, it triggers checkpoint when
++ * parent's xattr metadata was updated.
++ */
++ if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT)
++ set_sbi_flag(sbi, SBI_NEED_CP);
++ else
++ f2fs_add_ino_entry(sbi, inode->i_ino, XATTR_DIR_INO);
+ same:
+ if (is_inode_flag_set(inode, FI_ACL_MODE)) {
+ inode->i_mode = F2FS_I(inode)->i_acl_mode;
+diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h
+index 8670adaa23f91..5948d11a2244b 100644
+--- a/include/trace/events/f2fs.h
++++ b/include/trace/events/f2fs.h
+@@ -145,7 +145,8 @@ TRACE_DEFINE_ENUM(CP_RESIZE);
+ { CP_NODE_NEED_CP, "node needs cp" }, \
+ { CP_FASTBOOT_MODE, "fastboot mode" }, \
+ { CP_SPEC_LOG_NUM, "log type is 2" }, \
+- { CP_RECOVER_DIR, "dir needs recovery" })
++ { CP_RECOVER_DIR, "dir needs recovery" }, \
++ { CP_XATTR_DIR, "dir's xattr updated" })
+
+ #define show_shutdown_mode(type) \
+ __print_symbolic(type, \
+--
+2.43.0
+
--- /dev/null
+From 4e41c23cc6cd7772a762a1a535798e21df6c9f35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Jul 2023 21:50:46 +0800
+Subject: f2fs: remove unneeded check condition in __f2fs_setxattr()
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit bc3994ffa4cf23f55171943c713366132c3ff45d ]
+
+It has checked return value of write_all_xattrs(), remove unneeded
+following check condition.
+
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Stable-dep-of: aaf8c0b9ae04 ("f2fs: reduce expensive checkpoint trigger frequency")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/xattr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
+index 4f2069bf2b4bc..ec019feab062e 100644
+--- a/fs/f2fs/xattr.c
++++ b/fs/f2fs/xattr.c
+@@ -760,7 +760,7 @@ static int __f2fs_setxattr(struct inode *inode, int index,
+ if (index == F2FS_XATTR_INDEX_ENCRYPTION &&
+ !strcmp(name, F2FS_XATTR_NAME_ENCRYPTION_CONTEXT))
+ f2fs_set_encrypted_inode(inode);
+- if (!error && S_ISDIR(inode->i_mode))
++ if (S_ISDIR(inode->i_mode))
+ set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_CP);
+
+ same:
+--
+2.43.0
+
--- /dev/null
+From 9175e071473c8f593d922da8ec665cf4c09b6eee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Aug 2024 22:34:39 +0200
+Subject: fbdev: hpfb: Fix an error handling path in hpfb_dio_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit aa578e897520f32ae12bec487f2474357d01ca9c ]
+
+If an error occurs after request_mem_region(), a corresponding
+release_mem_region() should be called, as already done in the remove
+function.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/hpfb.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/video/fbdev/hpfb.c b/drivers/video/fbdev/hpfb.c
+index 8d418abdd7678..1e9c52e2714dd 100644
+--- a/drivers/video/fbdev/hpfb.c
++++ b/drivers/video/fbdev/hpfb.c
+@@ -344,6 +344,7 @@ static int hpfb_dio_probe(struct dio_dev *d, const struct dio_device_id *ent)
+ if (hpfb_init_one(paddr, vaddr)) {
+ if (d->scode >= DIOII_SCBASE)
+ iounmap((void *)vaddr);
++ release_mem_region(d->resource.start, resource_size(&d->resource));
+ return -ENOMEM;
+ }
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From c023bb2972707e78d63919c64568227c19bd857e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Nov 2021 13:36:58 -0700
+Subject: fs: explicitly unregister per-superblock BDIs
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 0b3ea0926afb8dde70cfab00316ae0a70b93a7cc ]
+
+Add a new SB_I_ flag to mark superblocks that have an ephemeral bdi
+associated with them, and unregister it when the superblock is shut
+down.
+
+Link: https://lkml.kernel.org/r/20211021124441.668816-4-hch@lst.de
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Cc: Miquel Raynal <miquel.raynal@bootlin.com>
+Cc: Richard Weinberger <richard@nod.at>
+Cc: Vignesh Raghavendra <vigneshr@ti.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Stable-dep-of: 4bcda1eaf184 ("mount: handle OOM on mnt_warn_timestamp_expiry")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/super.c | 3 +++
+ include/linux/fs.h | 1 +
+ 2 files changed, 4 insertions(+)
+
+diff --git a/fs/super.c b/fs/super.c
+index 39d866f7d7c6b..eeb8f745a8bf7 100644
+--- a/fs/super.c
++++ b/fs/super.c
+@@ -486,6 +486,8 @@ void generic_shutdown_super(struct super_block *sb)
+ spin_unlock(&sb_lock);
+ up_write(&sb->s_umount);
+ if (sb->s_bdi != &noop_backing_dev_info) {
++ if (sb->s_iflags & SB_I_PERSB_BDI)
++ bdi_unregister(sb->s_bdi);
+ bdi_put(sb->s_bdi);
+ sb->s_bdi = &noop_backing_dev_info;
+ }
+@@ -1592,6 +1594,7 @@ int super_setup_bdi_name(struct super_block *sb, char *fmt, ...)
+ }
+ WARN_ON(sb->s_bdi != &noop_backing_dev_info);
+ sb->s_bdi = bdi;
++ sb->s_iflags |= SB_I_PERSB_BDI;
+
+ return 0;
+ }
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 27da89d0ed5ac..bf35cf9e312a5 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1476,6 +1476,7 @@ extern int send_sigurg(struct fown_struct *fown);
+ #define SB_I_UNTRUSTED_MOUNTER 0x00000040
+
+ #define SB_I_SKIP_SYNC 0x00000100 /* Skip superblock at global sync */
++#define SB_I_PERSB_BDI 0x00000200 /* has a per-sb bdi */
+
+ /* Possible states of 'frozen' field */
+ enum {
+--
+2.43.0
+
--- /dev/null
+From 0071a651458e5aaf3dfd7038160c4357fdff6239 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Mar 2023 17:09:06 +0200
+Subject: fs/namespace: fnic: Switch to use %ptTd
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 74e60b8b2f0fe3702710e648a31725ee8224dbdf ]
+
+Use %ptTd instead of open-coded variant to print contents
+of time64_t type in human readable form.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
+Stable-dep-of: 4bcda1eaf184 ("mount: handle OOM on mnt_warn_timestamp_expiry")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/namespace.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+diff --git a/fs/namespace.c b/fs/namespace.c
+index 04467a2a7888e..c17e3a6ebd179 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -2571,15 +2571,12 @@ static void mnt_warn_timestamp_expiry(struct path *mountpoint, struct vfsmount *
+ (ktime_get_real_seconds() + TIME_UPTIME_SEC_MAX > sb->s_time_max)) {
+ char *buf = (char *)__get_free_page(GFP_KERNEL);
+ char *mntpath = buf ? d_path(mountpoint, buf, PAGE_SIZE) : ERR_PTR(-ENOMEM);
+- struct tm tm;
+
+- time64_to_tm(sb->s_time_max, 0, &tm);
+-
+- pr_warn("%s filesystem being %s at %s supports timestamps until %04ld (0x%llx)\n",
++ pr_warn("%s filesystem being %s at %s supports timestamps until %ptTd (0x%llx)\n",
+ sb->s_type->name,
+ is_mounted(mnt) ? "remounted" : "mounted",
+- mntpath,
+- tm.tm_year+1900, (unsigned long long)sb->s_time_max);
++ mntpath, &sb->s_time_max,
++ (unsigned long long)sb->s_time_max);
+
+ free_page((unsigned long)buf);
+ sb->s_iflags |= SB_I_TS_EXPIRY_WARNED;
+--
+2.43.0
+
--- /dev/null
+From 22f9e9843700e99cdffd810412d5d9c19530e39f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Jun 2024 23:32:48 +0300
+Subject: geneve: Fix incorrect inner network header offset when
+ innerprotoinherit is set
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit c6ae073f5903f6c6439d0ac855836a4da5c0a701 ]
+
+When innerprotoinherit is set, the tunneled packets do not have an inner
+Ethernet header.
+Change 'maclen' to not always assume the header length is ETH_HLEN, as
+there might not be a MAC header.
+
+This resolves issues with drivers (e.g. mlx5, in
+mlx5e_tx_tunnel_accel()) who rely on the skb inner network header offset
+to be correct, and use it for TX offloads.
+
+Fixes: d8a6213d70ac ("geneve: fix header validation in geneve[6]_xmit_skb")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: c471236b2359 ("bareudp: Pull inner IP header on xmit.")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/geneve.c | 10 ++++++----
+ include/net/ip_tunnels.h | 5 +++--
+ 2 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
+index 6790fec36a6cb..623e139e81fec 100644
+--- a/drivers/net/geneve.c
++++ b/drivers/net/geneve.c
+@@ -914,6 +914,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ struct geneve_dev *geneve,
+ const struct ip_tunnel_info *info)
+ {
++ bool inner_proto_inherit = geneve->cfg.inner_proto_inherit;
+ bool xnet = !net_eq(geneve->net, dev_net(geneve->dev));
+ struct geneve_sock *gs4 = rcu_dereference(geneve->sock4);
+ const struct ip_tunnel_key *key = &info->key;
+@@ -925,7 +926,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ __be16 sport;
+ int err;
+
+- if (!skb_vlan_inet_prepare(skb))
++ if (!skb_vlan_inet_prepare(skb, inner_proto_inherit))
+ return -EINVAL;
+
+ sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
+@@ -998,7 +999,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ }
+
+ err = geneve_build_skb(&rt->dst, skb, info, xnet, sizeof(struct iphdr),
+- geneve->cfg.inner_proto_inherit);
++ inner_proto_inherit);
+ if (unlikely(err))
+ return err;
+
+@@ -1014,6 +1015,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ struct geneve_dev *geneve,
+ const struct ip_tunnel_info *info)
+ {
++ bool inner_proto_inherit = geneve->cfg.inner_proto_inherit;
+ bool xnet = !net_eq(geneve->net, dev_net(geneve->dev));
+ struct geneve_sock *gs6 = rcu_dereference(geneve->sock6);
+ const struct ip_tunnel_key *key = &info->key;
+@@ -1023,7 +1025,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ __be16 sport;
+ int err;
+
+- if (!skb_vlan_inet_prepare(skb))
++ if (!skb_vlan_inet_prepare(skb, inner_proto_inherit))
+ return -EINVAL;
+
+ sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
+@@ -1078,7 +1080,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ ttl = ttl ? : ip6_dst_hoplimit(dst);
+ }
+ err = geneve_build_skb(dst, skb, info, xnet, sizeof(struct ipv6hdr),
+- geneve->cfg.inner_proto_inherit);
++ inner_proto_inherit);
+ if (unlikely(err))
+ return err;
+
+diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
+index eca36edb85570..526b492ebf78d 100644
+--- a/include/net/ip_tunnels.h
++++ b/include/net/ip_tunnels.h
+@@ -334,9 +334,10 @@ static inline bool pskb_inet_may_pull(struct sk_buff *skb)
+
+ /* Variant of pskb_inet_may_pull().
+ */
+-static inline bool skb_vlan_inet_prepare(struct sk_buff *skb)
++static inline bool skb_vlan_inet_prepare(struct sk_buff *skb,
++ bool inner_proto_inherit)
+ {
+- int nhlen = 0, maclen = ETH_HLEN;
++ int nhlen = 0, maclen = inner_proto_inherit ? 0 : ETH_HLEN;
+ __be16 type = skb->protocol;
+
+ /* Essentially this is skb_protocol(skb, true)
+--
+2.43.0
+
--- /dev/null
+From 05b437b3758aeca149af074150a1ffe303b26a04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Jul 2024 06:41:17 -0700
+Subject: hwmon: (max16065) Fix alarm attributes
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 119abf7d1815f098f7f91ae7abc84324a19943d7 ]
+
+Chips reporting overcurrent alarms report it in the second alarm register.
+That means the second alarm register has to be read, even if the chip only
+supports 8 or fewer ADC channels.
+
+MAX16067 and MAX16068 report undervoltage and overvoltage alarms in
+separate registers. Fold register contents together to report both with
+the existing alarm attribute. This requires actually storing the chip type
+in struct max16065_data. Rename the variable 'chip' to match the variable
+name used in the probe function.
+
+Reviewed-by: Tzung-Bi Shih <tzungbi@kernel.org>
+Fixes: f5bae2642e3d ("hwmon: Driver for MAX16065 System Manager and compatibles")
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/max16065.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c
+index 174a2b9ea2b80..25de0065bdedd 100644
+--- a/drivers/hwmon/max16065.c
++++ b/drivers/hwmon/max16065.c
+@@ -79,7 +79,7 @@ static const bool max16065_have_current[] = {
+ };
+
+ struct max16065_data {
+- enum chips type;
++ enum chips chip;
+ struct i2c_client *client;
+ const struct attribute_group *groups[4];
+ struct mutex update_lock;
+@@ -162,10 +162,17 @@ static struct max16065_data *max16065_update_device(struct device *dev)
+ MAX16065_CURR_SENSE);
+ }
+
+- for (i = 0; i < DIV_ROUND_UP(data->num_adc, 8); i++)
++ for (i = 0; i < 2; i++)
+ data->fault[i]
+ = i2c_smbus_read_byte_data(client, MAX16065_FAULT(i));
+
++ /*
++ * MAX16067 and MAX16068 have separate undervoltage and
++ * overvoltage alarm bits. Squash them together.
++ */
++ if (data->chip == max16067 || data->chip == max16068)
++ data->fault[0] |= data->fault[1];
++
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+@@ -514,6 +521,7 @@ static int max16065_probe(struct i2c_client *client)
+ if (unlikely(!data))
+ return -ENOMEM;
+
++ data->chip = chip;
+ data->client = client;
+ mutex_init(&data->update_lock);
+
+--
+2.43.0
+
--- /dev/null
+From 13529a10320f51d713f62b954ede82909a8bc8a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Jul 2024 09:52:01 -0700
+Subject: hwmon: (max16065) Fix overflows seen when writing limits
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 744ec4477b11c42e2c8de9eb8364675ae7a0bd81 ]
+
+Writing large limits resulted in overflows as reported by module tests.
+
+in0_lcrit: Suspected overflow: [max=5538, read 0, written 2147483647]
+in0_crit: Suspected overflow: [max=5538, read 0, written 2147483647]
+in0_min: Suspected overflow: [max=5538, read 0, written 2147483647]
+
+Fix the problem by clamping prior to multiplications and the use of
+DIV_ROUND_CLOSEST, and by using consistent variable types.
+
+Reviewed-by: Tzung-Bi Shih <tzungbi@kernel.org>
+Fixes: f5bae2642e3d ("hwmon: Driver for MAX16065 System Manager and compatibles")
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/max16065.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c
+index ae3a6a7bdaa23..47d039c46cb09 100644
+--- a/drivers/hwmon/max16065.c
++++ b/drivers/hwmon/max16065.c
+@@ -114,9 +114,10 @@ static inline int LIMIT_TO_MV(int limit, int range)
+ return limit * range / 256;
+ }
+
+-static inline int MV_TO_LIMIT(int mv, int range)
++static inline int MV_TO_LIMIT(unsigned long mv, int range)
+ {
+- return clamp_val(DIV_ROUND_CLOSEST(mv * 256, range), 0, 255);
++ mv = clamp_val(mv, 0, ULONG_MAX / 256);
++ return DIV_ROUND_CLOSEST(clamp_val(mv * 256, 0, range * 255), range);
+ }
+
+ static inline int ADC_TO_CURR(int adc, int gain)
+--
+2.43.0
+
--- /dev/null
+From e392f8cc14a56e2f50c082b3ecdbb2bbef1dd342 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Apr 2024 15:36:21 -0500
+Subject: hwmon: (max16065) Remove use of i2c_match_id()
+
+From: Andrew Davis <afd@ti.com>
+
+[ Upstream commit 5a71654b398e3471f0169c266a3587cf09e1200c ]
+
+The function i2c_match_id() is used to fetch the matching ID from
+the i2c_device_id table. This is often used to then retrieve the
+matching driver_data. This can be done in one step with the helper
+i2c_get_match_data().
+
+This helper has a couple other benefits:
+ * It doesn't need the i2c_device_id passed in so we do not need
+ to have that forward declared, allowing us to remove those or
+ move the i2c_device_id table down to its more natural spot
+ with the other module info.
+ * It also checks for device match data, which allows for OF and
+ ACPI based probing. That means we do not have to manually check
+ those first and can remove those checks.
+
+Signed-off-by: Andrew Davis <afd@ti.com>
+Link: https://lore.kernel.org/r/20240403203633.914389-20-afd@ti.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Stable-dep-of: 119abf7d1815 ("hwmon: (max16065) Fix alarm attributes")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/max16065.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c
+index 47d039c46cb09..174a2b9ea2b80 100644
+--- a/drivers/hwmon/max16065.c
++++ b/drivers/hwmon/max16065.c
+@@ -494,8 +494,6 @@ static const struct attribute_group max16065_max_group = {
+ .is_visible = max16065_secondary_is_visible,
+ };
+
+-static const struct i2c_device_id max16065_id[];
+-
+ static int max16065_probe(struct i2c_client *client)
+ {
+ struct i2c_adapter *adapter = client->adapter;
+@@ -506,7 +504,7 @@ static int max16065_probe(struct i2c_client *client)
+ bool have_secondary; /* true if chip has secondary limits */
+ bool secondary_is_max = false; /* secondary limits reflect max */
+ int groups = 0;
+- const struct i2c_device_id *id = i2c_match_id(max16065_id, client);
++ enum chips chip = (uintptr_t)i2c_get_match_data(client);
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
+ | I2C_FUNC_SMBUS_READ_WORD_DATA))
+@@ -519,9 +517,9 @@ static int max16065_probe(struct i2c_client *client)
+ data->client = client;
+ mutex_init(&data->update_lock);
+
+- data->num_adc = max16065_num_adc[id->driver_data];
+- data->have_current = max16065_have_current[id->driver_data];
+- have_secondary = max16065_have_secondary[id->driver_data];
++ data->num_adc = max16065_num_adc[chip];
++ data->have_current = max16065_have_current[chip];
++ have_secondary = max16065_have_secondary[chip];
+
+ if (have_secondary) {
+ val = i2c_smbus_read_byte_data(client, MAX16065_SW_ENABLE);
+--
+2.43.0
+
--- /dev/null
+From f8ecb6fbfc254ee0b25e1bfbdb2d1094afc26382 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Aug 2024 08:30:21 +0000
+Subject: hwmon: (ntc_thermistor) fix module autoloading
+
+From: Yuntao Liu <liuyuntao12@huawei.com>
+
+[ Upstream commit b6964d66a07a9003868e428a956949e17ab44d7e ]
+
+Add MODULE_DEVICE_TABLE(), so modules could be properly autoloaded
+based on the alias from of_device_id table.
+
+Fixes: 9e8269de100d ("hwmon: (ntc_thermistor) Add DT with IIO support to NTC thermistor driver")
+Signed-off-by: Yuntao Liu <liuyuntao12@huawei.com>
+Message-ID: <20240815083021.756134-1-liuyuntao12@huawei.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/ntc_thermistor.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c
+index cf26c44f2b880..4414c6b313238 100644
+--- a/drivers/hwmon/ntc_thermistor.c
++++ b/drivers/hwmon/ntc_thermistor.c
+@@ -55,6 +55,7 @@ static const struct platform_device_id ntc_thermistor_id[] = {
+ [NTC_NCP21WB473] = { "ncp21wb473", TYPE_NCPXXWB473 },
+ [NTC_LAST] = { },
+ };
++MODULE_DEVICE_TABLE(platform, ntc_thermistor_id);
+
+ /*
+ * A compensation table should be sorted by the values of .ohm
+--
+2.43.0
+
--- /dev/null
+From 64745421b2d229e7e9646266ee0ba2ca8601e647 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Jun 2023 17:57:38 +0100
+Subject: i2c: Add i2c_get_match_data()
+
+From: Biju Das <biju.das.jz@bp.renesas.com>
+
+[ Upstream commit 564d73c4d9201526bd976b9379d2aaf1a7133e84 ]
+
+Add i2c_get_match_data() to get match data for I2C, ACPI and
+DT-based matching, so that we can optimize the driver code.
+
+Suggested-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
+[wsa: simplified var initialization]
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: 119abf7d1815 ("hwmon: (max16065) Fix alarm attributes")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/i2c-core-base.c | 19 +++++++++++++++++++
+ include/linux/i2c.h | 2 ++
+ 2 files changed, 21 insertions(+)
+
+diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
+index dccd94ee138e2..b163ef91aabab 100644
+--- a/drivers/i2c/i2c-core-base.c
++++ b/drivers/i2c/i2c-core-base.c
+@@ -113,6 +113,25 @@ const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
+ }
+ EXPORT_SYMBOL_GPL(i2c_match_id);
+
++const void *i2c_get_match_data(const struct i2c_client *client)
++{
++ struct i2c_driver *driver = to_i2c_driver(client->dev.driver);
++ const struct i2c_device_id *match;
++ const void *data;
++
++ data = device_get_match_data(&client->dev);
++ if (!data) {
++ match = i2c_match_id(driver->id_table, client);
++ if (!match)
++ return NULL;
++
++ data = (const void *)match->driver_data;
++ }
++
++ return data;
++}
++EXPORT_SYMBOL(i2c_get_match_data);
++
+ static int i2c_device_match(struct device *dev, struct device_driver *drv)
+ {
+ struct i2c_client *client = i2c_verify_client(dev);
+diff --git a/include/linux/i2c.h b/include/linux/i2c.h
+index 2fb2f83bd5015..8bcc0142c32c2 100644
+--- a/include/linux/i2c.h
++++ b/include/linux/i2c.h
+@@ -349,6 +349,8 @@ struct i2c_adapter *i2c_verify_adapter(struct device *dev);
+ const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
+ const struct i2c_client *client);
+
++const void *i2c_get_match_data(const struct i2c_client *client);
++
+ static inline struct i2c_client *kobj_to_i2c_client(struct kobject *kobj)
+ {
+ struct device * const dev = kobj_to_dev(kobj);
+--
+2.43.0
+
--- /dev/null
+From 520ee74d0803a7f0202674d3a412ababf580f3f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Sep 2024 13:36:33 +0300
+Subject: IB/core: Fix ib_cache_setup_one error flow cleanup
+
+From: Patrisious Haddad <phaddad@nvidia.com>
+
+[ Upstream commit 1403c8b14765eab805377dd3b75e96ace8747aed ]
+
+When ib_cache_update return an error, we exit ib_cache_setup_one
+instantly with no proper cleanup, even though before this we had
+already successfully done gid_table_setup_one, that results in
+the kernel WARN below.
+
+Do proper cleanup using gid_table_cleanup_one before returning
+the err in order to fix the issue.
+
+WARNING: CPU: 4 PID: 922 at drivers/infiniband/core/cache.c:806 gid_table_release_one+0x181/0x1a0
+Modules linked in:
+CPU: 4 UID: 0 PID: 922 Comm: c_repro Not tainted 6.11.0-rc1+ #3
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
+RIP: 0010:gid_table_release_one+0x181/0x1a0
+Code: 44 8b 38 75 0c e8 2f cb 34 ff 4d 8b b5 28 05 00 00 e8 23 cb 34 ff 44 89 f9 89 da 4c 89 f6 48 c7 c7 d0 58 14 83 e8 4f de 21 ff <0f> 0b 4c 8b 75 30 e9 54 ff ff ff 48 8 3 c4 10 5b 5d 41 5c 41 5d 41
+RSP: 0018:ffffc90002b835b0 EFLAGS: 00010286
+RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff811c8527
+RDX: 0000000000000000 RSI: ffffffff811c8534 RDI: 0000000000000001
+RBP: ffff8881011b3d00 R08: ffff88810b3abe00 R09: 205d303839303631
+R10: 666572207972746e R11: 72746e6520444947 R12: 0000000000000001
+R13: ffff888106390000 R14: ffff8881011f2110 R15: 0000000000000001
+FS: 00007fecc3b70800(0000) GS:ffff88813bd00000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000000020000340 CR3: 000000010435a001 CR4: 00000000003706b0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ <TASK>
+ ? show_regs+0x94/0xa0
+ ? __warn+0x9e/0x1c0
+ ? gid_table_release_one+0x181/0x1a0
+ ? report_bug+0x1f9/0x340
+ ? gid_table_release_one+0x181/0x1a0
+ ? handle_bug+0xa2/0x110
+ ? exc_invalid_op+0x31/0xa0
+ ? asm_exc_invalid_op+0x16/0x20
+ ? __warn_printk+0xc7/0x180
+ ? __warn_printk+0xd4/0x180
+ ? gid_table_release_one+0x181/0x1a0
+ ib_device_release+0x71/0xe0
+ ? __pfx_ib_device_release+0x10/0x10
+ device_release+0x44/0xd0
+ kobject_put+0x135/0x3d0
+ put_device+0x20/0x30
+ rxe_net_add+0x7d/0xa0
+ rxe_newlink+0xd7/0x190
+ nldev_newlink+0x1b0/0x2a0
+ ? __pfx_nldev_newlink+0x10/0x10
+ rdma_nl_rcv_msg+0x1ad/0x2e0
+ rdma_nl_rcv_skb.constprop.0+0x176/0x210
+ netlink_unicast+0x2de/0x400
+ netlink_sendmsg+0x306/0x660
+ __sock_sendmsg+0x110/0x120
+ ____sys_sendmsg+0x30e/0x390
+ ___sys_sendmsg+0x9b/0xf0
+ ? kstrtouint+0x6e/0xa0
+ ? kstrtouint_from_user+0x7c/0xb0
+ ? get_pid_task+0xb0/0xd0
+ ? proc_fail_nth_write+0x5b/0x140
+ ? __fget_light+0x9a/0x200
+ ? preempt_count_add+0x47/0xa0
+ __sys_sendmsg+0x61/0xd0
+ do_syscall_64+0x50/0x110
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Fixes: 1901b91f9982 ("IB/core: Fix potential NULL pointer dereference in pkey cache")
+Signed-off-by: Patrisious Haddad <phaddad@nvidia.com>
+Reviewed-by: Maher Sanalla <msanalla@nvidia.com>
+Link: https://patch.msgid.link/79137687d829899b0b1c9835fcb4b258004c439a.1725273354.git.leon@kernel.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cache.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
+index 98f3d8b382c15..b534ef03168c6 100644
+--- a/drivers/infiniband/core/cache.c
++++ b/drivers/infiniband/core/cache.c
+@@ -1623,8 +1623,10 @@ int ib_cache_setup_one(struct ib_device *device)
+
+ rdma_for_each_port (device, p) {
+ err = ib_cache_update(device, p, true, true, true);
+- if (err)
++ if (err) {
++ gid_table_cleanup_one(device);
+ return err;
++ }
+ }
+
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From 56b2db3b44ced12dca3fd37cfd98958a40914f41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jul 2024 17:34:10 +0000
+Subject: iio: adc: ad7606: fix oversampling gpio array
+
+From: Guillaume Stols <gstols@baylibre.com>
+
+[ Upstream commit 8dc4594b54dbaaba40dc8884ad3d42083de39434 ]
+
+gpiod_set_array_value was misused here: the implementation relied on the
+assumption that an unsigned long was required for each gpio, while the
+function expects a bit array stored in "as much unsigned long as needed
+for storing one bit per GPIO", i.e it is using a bit field.
+
+This leaded to incorrect parameter passed to gpiod_set_array_value, that
+would set 1 value instead of 3.
+It also prevents to select the software mode correctly for the AD7606B.
+
+Fixes: d2a415c86c6b ("iio: adc: ad7606: Add support for AD7606B ADC")
+Fixes: 41f71e5e7daf ("staging: iio: adc: ad7606: Use find_closest() macro")
+Signed-off-by: Guillaume Stols <gstols@baylibre.com>
+Reviewed-by: Nuno Sa <nuno.sa@analog.com>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7606.c | 4 ++--
+ drivers/iio/adc/ad7606_spi.c | 5 +++--
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c
+index 0a60ecc69d38e..0faed0a69d59c 100644
+--- a/drivers/iio/adc/ad7606.c
++++ b/drivers/iio/adc/ad7606.c
+@@ -238,9 +238,9 @@ static int ad7606_write_os_hw(struct iio_dev *indio_dev, int val)
+ struct ad7606_state *st = iio_priv(indio_dev);
+ DECLARE_BITMAP(values, 3);
+
+- values[0] = val;
++ values[0] = val & GENMASK(2, 0);
+
+- gpiod_set_array_value(ARRAY_SIZE(values), st->gpio_os->desc,
++ gpiod_set_array_value(st->gpio_os->ndescs, st->gpio_os->desc,
+ st->gpio_os->info, values);
+
+ /* AD7616 requires a reset to update value */
+diff --git a/drivers/iio/adc/ad7606_spi.c b/drivers/iio/adc/ad7606_spi.c
+index 29945ad07dca8..e1ad2cd61b7f9 100644
+--- a/drivers/iio/adc/ad7606_spi.c
++++ b/drivers/iio/adc/ad7606_spi.c
+@@ -249,8 +249,9 @@ static int ad7616_sw_mode_config(struct iio_dev *indio_dev)
+ static int ad7606B_sw_mode_config(struct iio_dev *indio_dev)
+ {
+ struct ad7606_state *st = iio_priv(indio_dev);
+- unsigned long os[3] = {1};
++ DECLARE_BITMAP(os, 3);
+
++ bitmap_fill(os, 3);
+ /*
+ * Software mode is enabled when all three oversampling
+ * pins are set to high. If oversampling gpios are defined
+@@ -258,7 +259,7 @@ static int ad7606B_sw_mode_config(struct iio_dev *indio_dev)
+ * otherwise, they must be hardwired to VDD
+ */
+ if (st->gpio_os) {
+- gpiod_set_array_value(ARRAY_SIZE(os),
++ gpiod_set_array_value(st->gpio_os->ndescs,
+ st->gpio_os->desc, st->gpio_os->info, os);
+ }
+ /* OS of 128 and 256 are available only in software mode */
+--
+2.43.0
+
--- /dev/null
+From 3fd389231d95a3a974d207c1610557e9cff010f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jul 2024 17:34:11 +0000
+Subject: iio: adc: ad7606: fix standby gpio state to match the documentation
+
+From: Guillaume Stols <gstols@baylibre.com>
+
+[ Upstream commit 059fe4f8bbdf5cad212e1aeeb3e8968c80b9ff3b ]
+
+The binding's documentation specifies that "As the line is active low, it
+should be marked GPIO_ACTIVE_LOW". However, in the driver, it was handled
+the opposite way. This commit sets the driver's behaviour in sync with the
+documentation
+
+Fixes: 722407a4e8c0 ("staging:iio:ad7606: Use GPIO descriptor API")
+Signed-off-by: Guillaume Stols <gstols@baylibre.com>
+Reviewed-by: Nuno Sa <nuno.sa@analog.com>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7606.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c
+index 0faed0a69d59c..cc5c3d994d348 100644
+--- a/drivers/iio/adc/ad7606.c
++++ b/drivers/iio/adc/ad7606.c
+@@ -445,7 +445,7 @@ static int ad7606_request_gpios(struct ad7606_state *st)
+ return PTR_ERR(st->gpio_range);
+
+ st->gpio_standby = devm_gpiod_get_optional(dev, "standby",
+- GPIOD_OUT_HIGH);
++ GPIOD_OUT_LOW);
+ if (IS_ERR(st->gpio_standby))
+ return PTR_ERR(st->gpio_standby);
+
+@@ -704,7 +704,7 @@ static int ad7606_suspend(struct device *dev)
+
+ if (st->gpio_standby) {
+ gpiod_set_value(st->gpio_range, 1);
+- gpiod_set_value(st->gpio_standby, 0);
++ gpiod_set_value(st->gpio_standby, 1);
+ }
+
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From afbe764b23838d25e799a4fdc284fca9d2d6d149 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Aug 2024 10:55:11 +0200
+Subject: Input: ilitek_ts_i2c - add report id message validation
+
+From: Emanuele Ghidoli <emanuele.ghidoli@toradex.com>
+
+[ Upstream commit 208989744a6f01bed86968473312d4e650e600b3 ]
+
+Ensure that the touchscreen response has correct "report id" byte
+before processing the touch data and discard other messages.
+
+Fixes: 42370681bd46 ("Input: Add support for ILITEK Lego Series")
+Signed-off-by: Emanuele Ghidoli <emanuele.ghidoli@toradex.com>
+Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
+Link: https://lore.kernel.org/r/20240805085511.43955-3-francesco@dolcini.it
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/touchscreen/ilitek_ts_i2c.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/input/touchscreen/ilitek_ts_i2c.c b/drivers/input/touchscreen/ilitek_ts_i2c.c
+index 43c3e068a8c35..41c928dc9d050 100644
+--- a/drivers/input/touchscreen/ilitek_ts_i2c.c
++++ b/drivers/input/touchscreen/ilitek_ts_i2c.c
+@@ -37,6 +37,8 @@
+ #define ILITEK_TP_CMD_GET_MCU_VER 0x61
+ #define ILITEK_TP_CMD_GET_IC_MODE 0xC0
+
++#define ILITEK_TP_I2C_REPORT_ID 0x48
++
+ #define REPORT_COUNT_ADDRESS 61
+ #define ILITEK_SUPPORT_MAX_POINT 40
+
+@@ -163,6 +165,11 @@ static int ilitek_process_and_report_v6(struct ilitek_ts_data *ts)
+ return error;
+ }
+
++ if (buf[0] != ILITEK_TP_I2C_REPORT_ID) {
++ dev_err(dev, "get touch info failed. Wrong id: 0x%02X\n", buf[0]);
++ return -EINVAL;
++ }
++
+ report_max_point = buf[REPORT_COUNT_ADDRESS];
+ if (report_max_point > ts->max_tp) {
+ dev_err(dev, "FW report max point:%d > panel info. max:%d\n",
+--
+2.43.0
+
--- /dev/null
+From 56739cd90d5de55875f82ee8487d4bf0126596da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Aug 2024 10:55:10 +0200
+Subject: Input: ilitek_ts_i2c - avoid wrong input subsystem sync
+
+From: Emanuele Ghidoli <emanuele.ghidoli@toradex.com>
+
+[ Upstream commit 7d0b18cd5dc7429917812963611d961fd93cb44d ]
+
+For different reasons i2c transaction may fail or report id in the
+message may be wrong. Avoid closing the frame in this case as it will
+result in all contacts being dropped, indicating that nothing is
+touching the screen anymore, while usually it is not the case.
+
+Fixes: 42370681bd46 ("Input: Add support for ILITEK Lego Series")
+Signed-off-by: Emanuele Ghidoli <emanuele.ghidoli@toradex.com>
+Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
+Link: https://lore.kernel.org/r/20240805085511.43955-2-francesco@dolcini.it
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/touchscreen/ilitek_ts_i2c.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/input/touchscreen/ilitek_ts_i2c.c b/drivers/input/touchscreen/ilitek_ts_i2c.c
+index c5d259c76adc1..43c3e068a8c35 100644
+--- a/drivers/input/touchscreen/ilitek_ts_i2c.c
++++ b/drivers/input/touchscreen/ilitek_ts_i2c.c
+@@ -160,15 +160,14 @@ static int ilitek_process_and_report_v6(struct ilitek_ts_data *ts)
+ error = ilitek_i2c_write_and_read(ts, NULL, 0, 0, buf, 64);
+ if (error) {
+ dev_err(dev, "get touch info failed, err:%d\n", error);
+- goto err_sync_frame;
++ return error;
+ }
+
+ report_max_point = buf[REPORT_COUNT_ADDRESS];
+ if (report_max_point > ts->max_tp) {
+ dev_err(dev, "FW report max point:%d > panel info. max:%d\n",
+ report_max_point, ts->max_tp);
+- error = -EINVAL;
+- goto err_sync_frame;
++ return -EINVAL;
+ }
+
+ count = DIV_ROUND_UP(report_max_point, packet_max_point);
+@@ -178,7 +177,7 @@ static int ilitek_process_and_report_v6(struct ilitek_ts_data *ts)
+ if (error) {
+ dev_err(dev, "get touch info. failed, cnt:%d, err:%d\n",
+ count, error);
+- goto err_sync_frame;
++ return error;
+ }
+ }
+
+@@ -203,10 +202,10 @@ static int ilitek_process_and_report_v6(struct ilitek_ts_data *ts)
+ ilitek_touch_down(ts, id, x, y);
+ }
+
+-err_sync_frame:
+ input_mt_sync_frame(input);
+ input_sync(input);
+- return error;
++
++ return 0;
+ }
+
+ /* APIs of cmds for ILITEK Touch IC */
+--
+2.43.0
+
--- /dev/null
+From 2d007ddec282076923c4d84d6b12858b9f44594a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Sep 2024 11:30:13 +0800
+Subject: Input: ps2-gpio - use IRQF_NO_AUTOEN flag in request_irq()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit dcd18a3fb1228409dfc24373c5c6868a655810b0 ]
+
+disable_irq() after request_irq() still has a time gap in which
+interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will
+disable IRQ auto-enable when request IRQ.
+
+Fixes: 9ee0a0558819 ("Input: PS/2 gpio bit banging driver for serio bus")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Acked-by: Danilo Krummrich <dakr@kernel.org>
+Link: https://lore.kernel.org/r/20240912033013.2610949-1-ruanjinjie@huawei.com
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/serio/ps2-gpio.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/input/serio/ps2-gpio.c b/drivers/input/serio/ps2-gpio.c
+index 8970b49ea09a2..b0238a8b5c210 100644
+--- a/drivers/input/serio/ps2-gpio.c
++++ b/drivers/input/serio/ps2-gpio.c
+@@ -374,16 +374,14 @@ static int ps2_gpio_probe(struct platform_device *pdev)
+ }
+
+ error = devm_request_irq(dev, drvdata->irq, ps2_gpio_irq,
+- IRQF_NO_THREAD, DRIVER_NAME, drvdata);
++ IRQF_NO_THREAD | IRQF_NO_AUTOEN, DRIVER_NAME,
++ drvdata);
+ if (error) {
+ dev_err(dev, "failed to request irq %d: %d\n",
+ drvdata->irq, error);
+ goto err_free_serio;
+ }
+
+- /* Keep irq disabled until serio->open is called. */
+- disable_irq(drvdata->irq);
+-
+ serio->id.type = SERIO_8042;
+ serio->open = ps2_gpio_open;
+ serio->close = ps2_gpio_close;
+--
+2.43.0
+
--- /dev/null
+From e87f5a8fa593e35c9fa0f31fdf56cd53e7e00906 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Nov 2023 15:04:45 +0100
+Subject: interconnect: qcom: sm8250: Enable sync_state
+
+From: Konrad Dybcio <konrad.dybcio@linaro.org>
+
+[ Upstream commit bfc7db1cb94ad664546d70212699f8cc6c539e8c ]
+
+Add the generic icc sync_state callback to ensure interconnect votes
+are taken into account, instead of being pegged at maximum values.
+
+Fixes: b95b668eaaa2 ("interconnect: qcom: icc-rpmh: Add BCMs to commit list in pre_aggregate")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20231130-topic-8250icc_syncstate-v1-1-7ce78ba6e04c@linaro.org
+Signed-off-by: Georgi Djakov <djakov@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/interconnect/qcom/sm8250.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/interconnect/qcom/sm8250.c b/drivers/interconnect/qcom/sm8250.c
+index aa707582ea016..8dfb5dea562a3 100644
+--- a/drivers/interconnect/qcom/sm8250.c
++++ b/drivers/interconnect/qcom/sm8250.c
+@@ -551,6 +551,7 @@ static struct platform_driver qnoc_driver = {
+ .driver = {
+ .name = "qnoc-sm8250",
+ .of_match_table = qnoc_of_match,
++ .sync_state = icc_sync_state,
+ },
+ };
+ module_platform_driver(qnoc_driver);
+--
+2.43.0
+
--- /dev/null
+From cee102f129fb94f27ea9b47819420c07baf8dd76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 1 Sep 2024 11:02:11 +0200
+Subject: ipmi: docs: don't advertise deprecated sysfs entries
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit 64dce81f8c373c681e62d5ffe0397c45a35d48a2 ]
+
+"i2c-adapter" class entries are deprecated since 2009. Switch to the
+proper location.
+
+Reported-by: Heiner Kallweit <hkallweit1@gmail.com>
+Closes: https://lore.kernel.org/r/80c4a898-5867-4162-ac85-bdf7c7c68746@gmail.com
+Fixes: 259307074bfc ("ipmi: Add SMBus interface driver (SSIF)")
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Message-Id: <20240901090211.3797-2-wsa+renesas@sang-engineering.com>
+Signed-off-by: Corey Minyard <corey@minyard.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/driver-api/ipmi.rst | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Documentation/driver-api/ipmi.rst b/Documentation/driver-api/ipmi.rst
+index bc281f10ce4b7..0bfeeeeb17c85 100644
+--- a/Documentation/driver-api/ipmi.rst
++++ b/Documentation/driver-api/ipmi.rst
+@@ -519,7 +519,7 @@ at module load time (for a module) with::
+ alerts_broken
+
+ The addresses are normal I2C addresses. The adapter is the string
+-name of the adapter, as shown in /sys/class/i2c-adapter/i2c-<n>/name.
++name of the adapter, as shown in /sys/bus/i2c/devices/i2c-<n>/name.
+ It is *NOT* i2c-<n> itself. Also, the comparison is done ignoring
+ spaces, so if the name is "This is an I2C chip" you can say
+ adapter_name=ThisisanI2cchip. This is because it's hard to pass in
+--
+2.43.0
+
--- /dev/null
+From 01b0ef9ea68b69e6763eccfd5444cc05d1e43f36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Aug 2024 13:05:46 +0900
+Subject: jfs: fix out-of-bounds in dbNextAG() and diAlloc()
+
+From: Jeongjun Park <aha310510@gmail.com>
+
+[ Upstream commit e63866a475562810500ea7f784099bfe341e761a ]
+
+In dbNextAG() , there is no check for the case where bmp->db_numag is
+greater or same than MAXAG due to a polluted image, which causes an
+out-of-bounds. Therefore, a bounds check should be added in dbMount().
+
+And in dbNextAG(), a check for the case where agpref is greater than
+bmp->db_numag should be added, so an out-of-bounds exception should be
+prevented.
+
+Additionally, a check for the case where agno is greater or same than
+MAXAG should be added in diAlloc() to prevent out-of-bounds.
+
+Reported-by: Jeongjun Park <aha310510@gmail.com>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Jeongjun Park <aha310510@gmail.com>
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jfs/jfs_dmap.c | 4 ++--
+ fs/jfs/jfs_imap.c | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
+index 3f5c14315719b..625457e94b30a 100644
+--- a/fs/jfs/jfs_dmap.c
++++ b/fs/jfs/jfs_dmap.c
+@@ -187,7 +187,7 @@ int dbMount(struct inode *ipbmap)
+ }
+
+ bmp->db_numag = le32_to_cpu(dbmp_le->dn_numag);
+- if (!bmp->db_numag) {
++ if (!bmp->db_numag || bmp->db_numag >= MAXAG) {
+ err = -EINVAL;
+ goto err_release_metapage;
+ }
+@@ -652,7 +652,7 @@ int dbNextAG(struct inode *ipbmap)
+ * average free space.
+ */
+ for (i = 0 ; i < bmp->db_numag; i++, agpref++) {
+- if (agpref == bmp->db_numag)
++ if (agpref >= bmp->db_numag)
+ agpref = 0;
+
+ if (atomic_read(&bmp->db_active[agpref]))
+diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
+index ba6f28521360b..c72e97f065798 100644
+--- a/fs/jfs/jfs_imap.c
++++ b/fs/jfs/jfs_imap.c
+@@ -1360,7 +1360,7 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip)
+ /* get the ag number of this iag */
+ agno = BLKTOAG(JFS_IP(pip)->agstart, JFS_SBI(pip->i_sb));
+ dn_numag = JFS_SBI(pip->i_sb)->bmap->db_numag;
+- if (agno < 0 || agno > dn_numag)
++ if (agno < 0 || agno > dn_numag || agno >= MAXAG)
+ return -EIO;
+
+ if (atomic_read(&JFS_SBI(pip->i_sb)->bmap->db_active[agno])) {
+--
+2.43.0
+
--- /dev/null
+From 7233ef292eebb86c548a7dd76af769168347e83e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Aug 2024 19:23:08 +0800
+Subject: kthread: fix task state in kthread worker if being frozen
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Chen Yu <yu.c.chen@intel.com>
+
+[ Upstream commit e16c7b07784f3fb03025939c4590b9a7c64970a7 ]
+
+When analyzing a kernel waring message, Peter pointed out that there is a
+race condition when the kworker is being frozen and falls into
+try_to_freeze() with TASK_INTERRUPTIBLE, which could trigger a
+might_sleep() warning in try_to_freeze(). Although the root cause is not
+related to freeze()[1], it is still worthy to fix this issue ahead.
+
+One possible race scenario:
+
+ CPU 0 CPU 1
+ ----- -----
+
+ // kthread_worker_fn
+ set_current_state(TASK_INTERRUPTIBLE);
+ suspend_freeze_processes()
+ freeze_processes
+ static_branch_inc(&freezer_active);
+ freeze_kernel_threads
+ pm_nosig_freezing = true;
+ if (work) { //false
+ __set_current_state(TASK_RUNNING);
+
+ } else if (!freezing(current)) //false, been frozen
+
+ freezing():
+ if (static_branch_unlikely(&freezer_active))
+ if (pm_nosig_freezing)
+ return true;
+ schedule()
+ }
+
+ // state is still TASK_INTERRUPTIBLE
+ try_to_freeze()
+ might_sleep() <--- warning
+
+Fix this by explicitly set the TASK_RUNNING before entering
+try_to_freeze().
+
+Link: https://lore.kernel.org/lkml/Zs2ZoAcUsZMX2B%2FI@chenyu5-mobl2/ [1]
+Link: https://lkml.kernel.org/r/20240827112308.181081-1-yu.c.chen@intel.com
+Fixes: b56c0d8937e6 ("kthread: implement kthread_worker")
+Signed-off-by: Chen Yu <yu.c.chen@intel.com>
+Suggested-by: Peter Zijlstra <peterz@infradead.org>
+Suggested-by: Andrew Morton <akpm@linux-foundation.org>
+Cc: Andreas Gruenbacher <agruenba@redhat.com>
+Cc: David Gow <davidgow@google.com>
+Cc: Mateusz Guzik <mjguzik@gmail.com>
+Cc: Mickaël Salaün <mic@digikod.net>
+Cc: Tejun Heo <tj@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/kthread.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/kthread.c b/kernel/kthread.c
+index 4cc6897b7ca40..13cfe01ed2fc7 100644
+--- a/kernel/kthread.c
++++ b/kernel/kthread.c
+@@ -781,8 +781,16 @@ int kthread_worker_fn(void *worker_ptr)
+ * event only cares about the address.
+ */
+ trace_sched_kthread_work_execute_end(work, func);
+- } else if (!freezing(current))
++ } else if (!freezing(current)) {
+ schedule();
++ } else {
++ /*
++ * Handle the case where the current remains
++ * TASK_INTERRUPTIBLE. try_to_freeze() expects
++ * the current to be TASK_RUNNING.
++ */
++ __set_current_state(TASK_RUNNING);
++ }
+
+ try_to_freeze();
+ cond_resched();
+--
+2.43.0
+
--- /dev/null
+From e45a35a35fcd6cfa1398192280701e9d811f6da2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Aug 2024 10:12:29 +1000
+Subject: m68k: Fix kernel_clone_args.flags in m68k_clone()
+
+From: Finn Thain <fthain@linux-m68k.org>
+
+[ Upstream commit 09b3d870faa7bc3e96c0978ab3cf4e96e4b15571 ]
+
+Stan Johnson recently reported a failure from the 'dump' command:
+
+ DUMP: Date of this level 0 dump: Fri Aug 9 23:37:15 2024
+ DUMP: Dumping /dev/sda (an unlisted file system) to /dev/null
+ DUMP: Label: none
+ DUMP: Writing 10 Kilobyte records
+ DUMP: mapping (Pass I) [regular files]
+ DUMP: mapping (Pass II) [directories]
+ DUMP: estimated 3595695 blocks.
+ DUMP: Context save fork fails in parent 671
+
+The dump program uses the clone syscall with the CLONE_IO flag, that is,
+flags == 0x80000000. When that value is promoted from long int to u64 by
+m68k_clone(), it undergoes sign-extension. The new value includes
+CLONE_INTO_CGROUP so the validation in cgroup_css_set_fork() fails and
+the syscall returns -EBADF. Avoid sign-extension by casting to u32.
+
+Reported-by: Stan Johnson <userm57@yahoo.com>
+Closes: https://lists.debian.org/debian-68k/2024/08/msg00000.html
+Fixes: 6aabc1facdb2 ("m68k: Implement copy_thread_tls()")
+Signed-off-by: Finn Thain <fthain@linux-m68k.org>
+Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Link: https://lore.kernel.org/3463f1e5d4e95468dc9f3368f2b78ffa7b72199b.1723335149.git.fthain@linux-m68k.org
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/m68k/kernel/process.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
+index 1ab692b952cd6..32427aa131667 100644
+--- a/arch/m68k/kernel/process.c
++++ b/arch/m68k/kernel/process.c
+@@ -116,7 +116,7 @@ asmlinkage int m68k_clone(struct pt_regs *regs)
+ {
+ /* regs will be equal to current_pt_regs() */
+ struct kernel_clone_args args = {
+- .flags = regs->d1 & ~CSIGNAL,
++ .flags = (u32)(regs->d1) & ~CSIGNAL,
+ .pidfd = (int __user *)regs->d3,
+ .child_tid = (int __user *)regs->d4,
+ .parent_tid = (int __user *)regs->d3,
+--
+2.43.0
+
--- /dev/null
+From 194be39a007696bbdabe9cdafb1e02ad4d28230d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Jul 2024 15:09:07 -0700
+Subject: minmax: avoid overly complex min()/max() macro arguments in xen
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+[ Upstream commit e8432ac802a028eaee6b1e86383d7cd8e9fb8431 ]
+
+We have some very fancy min/max macros that have tons of sanity checking
+to warn about mixed signedness etc.
+
+This is all things that a sane compiler should warn about, but there are
+no sane compiler interfaces for this, and '-Wsign-compare' is broken [1]
+and not useful.
+
+So then we compensate (some would say over-compensate) by doing the
+checks manually with some truly horrid macro games.
+
+And no, we can't just use __builtin_types_compatible_p(), because the
+whole question of "does it make sense to compare these two values" is a
+lot more complicated than that.
+
+For example, it makes a ton of sense to compare unsigned values with
+simple constants like "5", even if that is indeed a signed type. So we
+have these very strange macros to try to make sensible type checking
+decisions on the arguments to 'min()' and 'max()'.
+
+But that can cause enormous code expansion if the min()/max() macros are
+used with complicated expressions, and particularly if you nest these
+things so that you get the first big expansion then expanded again.
+
+The xen setup.c file ended up ballooning to over 50MB of preprocessed
+noise that takes 15s to compile (obviously depending on the build host),
+largely due to one single line.
+
+So let's split that one single line to just be simpler. I think it ends
+up being more legible to humans too at the same time. Now that single
+file compiles in under a second.
+
+Reported-and-reviewed-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
+Link: https://lore.kernel.org/all/c83c17bb-be75-4c67-979d-54eee38774c6@lucifer.local/
+Link: https://staticthinking.wordpress.com/2023/07/25/wsign-compare-is-garbage/ [1]
+Cc: David Laight <David.Laight@aculab.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Stable-dep-of: be35d91c8880 ("xen: tolerate ACPI NVS memory overlapping with Xen allocated memory")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/xen/setup.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
+index 629c94d1ab24c..dfb11a7420a3f 100644
+--- a/arch/x86/xen/setup.c
++++ b/arch/x86/xen/setup.c
+@@ -734,6 +734,7 @@ char * __init xen_memory_setup(void)
+ struct xen_memory_map memmap;
+ unsigned long max_pages;
+ unsigned long extra_pages = 0;
++ unsigned long maxmem_pages;
+ int i;
+ int op;
+
+@@ -796,8 +797,8 @@ char * __init xen_memory_setup(void)
+ * Make sure we have no memory above max_pages, as this area
+ * isn't handled by the p2m management.
+ */
+- extra_pages = min3(EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)),
+- extra_pages, max_pages - max_pfn);
++ maxmem_pages = EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM));
++ extra_pages = min3(maxmem_pages, extra_pages, max_pages - max_pfn);
+ i = 0;
+ addr = xen_e820_table.entries[0].addr;
+ size = xen_e820_table.entries[0].size;
+--
+2.43.0
+
--- /dev/null
+From edf5b793e14e480399c03adb14a7128f98590271 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 17:16:19 +0800
+Subject: mm: Add PAGE_ALIGN_DOWN macro
+
+From: David Gow <davidgow@google.com>
+
+[ Upstream commit 335e52c28cf9954d65b819cb68912fd32de3c844 ]
+
+This is just the same as PAGE_ALIGN(), but rounds the address down, not
+up.
+
+Suggested-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: David Gow <davidgow@google.com>
+Acked-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Stable-dep-of: be35d91c8880 ("xen: tolerate ACPI NVS memory overlapping with Xen allocated memory")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/mm.h | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index 5692055f202cb..f26b044024416 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -233,6 +233,9 @@ int __add_to_page_cache_locked(struct page *page, struct address_space *mapping,
+ /* to align the pointer to the (next) page boundary */
+ #define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE)
+
++/* to align the pointer to the (prev) page boundary */
++#define PAGE_ALIGN_DOWN(addr) ALIGN_DOWN(addr, PAGE_SIZE)
++
+ /* test whether an address (unsigned long or pointer) is aligned to PAGE_SIZE */
+ #define PAGE_ALIGNED(addr) IS_ALIGNED((unsigned long)(addr), PAGE_SIZE)
+
+--
+2.43.0
+
--- /dev/null
+From 1a0a2d006d1315ae49d2eef62270e72f39875699 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Jul 2024 10:58:13 +0200
+Subject: mount: handle OOM on mnt_warn_timestamp_expiry
+
+From: Olaf Hering <olaf@aepfle.de>
+
+[ Upstream commit 4bcda1eaf184e308f07f9c61d3a535f9ce477ce8 ]
+
+If no page could be allocated, an error pointer was used as format
+string in pr_warn.
+
+Rearrange the code to return early in case of OOM. Also add a check
+for the return value of d_path.
+
+Fixes: f8b92ba67c5d ("mount: Add mount warning for impending timestamp expiry")
+Signed-off-by: Olaf Hering <olaf@aepfle.de>
+Link: https://lore.kernel.org/r/20240730085856.32385-1-olaf@aepfle.de
+[brauner: rewrite commit and commit message]
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/namespace.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/fs/namespace.c b/fs/namespace.c
+index c17e3a6ebd179..22af4b6c737f4 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -2569,8 +2569,15 @@ static void mnt_warn_timestamp_expiry(struct path *mountpoint, struct vfsmount *
+ if (!__mnt_is_readonly(mnt) &&
+ (!(sb->s_iflags & SB_I_TS_EXPIRY_WARNED)) &&
+ (ktime_get_real_seconds() + TIME_UPTIME_SEC_MAX > sb->s_time_max)) {
+- char *buf = (char *)__get_free_page(GFP_KERNEL);
+- char *mntpath = buf ? d_path(mountpoint, buf, PAGE_SIZE) : ERR_PTR(-ENOMEM);
++ char *buf, *mntpath;
++
++ buf = (char *)__get_free_page(GFP_KERNEL);
++ if (buf)
++ mntpath = d_path(mountpoint, buf, PAGE_SIZE);
++ else
++ mntpath = ERR_PTR(-ENOMEM);
++ if (IS_ERR(mntpath))
++ mntpath = "(unknown)";
+
+ pr_warn("%s filesystem being %s at %s supports timestamps until %ptTd (0x%llx)\n",
+ sb->s_type->name,
+@@ -2578,8 +2585,9 @@ static void mnt_warn_timestamp_expiry(struct path *mountpoint, struct vfsmount *
+ mntpath, &sb->s_time_max,
+ (unsigned long long)sb->s_time_max);
+
+- free_page((unsigned long)buf);
+ sb->s_iflags |= SB_I_TS_EXPIRY_WARNED;
++ if (buf)
++ free_page((unsigned long)buf);
+ }
+ }
+
+--
+2.43.0
+
--- /dev/null
+From ff7bcdaa483dff869c0cde602fa92a82b7682d86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Mar 2022 14:39:22 -0700
+Subject: mount: warn only once about timestamp range expiration
+
+From: Anthony Iliopoulos <ailiop@suse.com>
+
+[ Upstream commit a128b054ce029554a4a52fc3abb8c1df8bafcaef ]
+
+Commit f8b92ba67c5d ("mount: Add mount warning for impending timestamp
+expiry") introduced a mount warning regarding filesystem timestamp
+limits, that is printed upon each writable mount or remount.
+
+This can result in a lot of unnecessary messages in the kernel log in
+setups where filesystems are being frequently remounted (or mounted
+multiple times).
+
+Avoid this by setting a superblock flag which indicates that the warning
+has been emitted at least once for any particular mount, as suggested in
+[1].
+
+Link: https://lore.kernel.org/CAHk-=wim6VGnxQmjfK_tDg6fbHYKL4EFkmnTjVr9QnRqjDBAeA@mail.gmail.com/ [1]
+Link: https://lkml.kernel.org/r/20220119202934.26495-1-ailiop@suse.com
+Signed-off-by: Anthony Iliopoulos <ailiop@suse.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Acked-by: Christian Brauner <christian.brauner@ubuntu.com>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Cc: Alexander Viro <viro@zeniv.linux.org.uk>
+Cc: Deepa Dinamani <deepa.kernel@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Stable-dep-of: 4bcda1eaf184 ("mount: handle OOM on mnt_warn_timestamp_expiry")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/namespace.c | 2 ++
+ include/linux/fs.h | 1 +
+ 2 files changed, 3 insertions(+)
+
+diff --git a/fs/namespace.c b/fs/namespace.c
+index 932986448a98a..04467a2a7888e 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -2567,6 +2567,7 @@ static void mnt_warn_timestamp_expiry(struct path *mountpoint, struct vfsmount *
+ struct super_block *sb = mnt->mnt_sb;
+
+ if (!__mnt_is_readonly(mnt) &&
++ (!(sb->s_iflags & SB_I_TS_EXPIRY_WARNED)) &&
+ (ktime_get_real_seconds() + TIME_UPTIME_SEC_MAX > sb->s_time_max)) {
+ char *buf = (char *)__get_free_page(GFP_KERNEL);
+ char *mntpath = buf ? d_path(mountpoint, buf, PAGE_SIZE) : ERR_PTR(-ENOMEM);
+@@ -2581,6 +2582,7 @@ static void mnt_warn_timestamp_expiry(struct path *mountpoint, struct vfsmount *
+ tm.tm_year+1900, (unsigned long long)sb->s_time_max);
+
+ free_page((unsigned long)buf);
++ sb->s_iflags |= SB_I_TS_EXPIRY_WARNED;
+ }
+ }
+
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index bf35cf9e312a5..6ff6ade229a07 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1477,6 +1477,7 @@ extern int send_sigurg(struct fown_struct *fown);
+
+ #define SB_I_SKIP_SYNC 0x00000100 /* Skip superblock at global sync */
+ #define SB_I_PERSB_BDI 0x00000200 /* has a per-sb bdi */
++#define SB_I_TS_EXPIRY_WARNED 0x00000400 /* warned about timestamp range expiry */
+
+ /* Possible states of 'frozen' field */
+ enum {
+--
+2.43.0
+
--- /dev/null
+From 3ad1fa50cf57604bdc0ec195f7640e1f52d20fe4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Aug 2024 17:24:27 +0800
+Subject: mtd: powernv: Add check devm_kasprintf() returned value
+
+From: Charles Han <hanchunchao@inspur.com>
+
+[ Upstream commit 395999829880a106bb95f0ce34e6e4c2b43c6a5d ]
+
+devm_kasprintf() can return a NULL pointer on failure but this
+returned value is not checked.
+
+Fixes: acfe63ec1c59 ("mtd: Convert to using %pOFn instead of device_node.name")
+Signed-off-by: Charles Han <hanchunchao@inspur.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20240828092427.128177-1-hanchunchao@inspur.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/devices/powernv_flash.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/mtd/devices/powernv_flash.c b/drivers/mtd/devices/powernv_flash.c
+index 6950a87648151..1277ca677becf 100644
+--- a/drivers/mtd/devices/powernv_flash.c
++++ b/drivers/mtd/devices/powernv_flash.c
+@@ -207,6 +207,9 @@ static int powernv_flash_set_driver_info(struct device *dev,
+ * get them
+ */
+ mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%pOFP", dev->of_node);
++ if (!mtd->name)
++ return -ENOMEM;
++
+ mtd->type = MTD_NORFLASH;
+ mtd->flags = MTD_WRITEABLE;
+ mtd->size = size;
+--
+2.43.0
+
--- /dev/null
+From f727637b10bf24643b4318c3beb23129008efb18 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jul 2024 01:43:20 +0200
+Subject: mtd: slram: insert break after errors in parsing the map
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mirsad Todorovac <mtodorovac69@gmail.com>
+
+[ Upstream commit 336c218dd7f0588ed8a7345f367975a00a4f003f ]
+
+GCC 12.3.0 compiler on linux-next next-20240709 tree found the execution
+path in which, due to lazy evaluation, devlength isn't initialised with the
+parsed string:
+
+ 289 while (map) {
+ 290 devname = devstart = devlength = NULL;
+ 291
+ 292 if (!(devname = strsep(&map, ","))) {
+ 293 E("slram: No devicename specified.\n");
+ 294 break;
+ 295 }
+ 296 T("slram: devname = %s\n", devname);
+ 297 if ((!map) || (!(devstart = strsep(&map, ",")))) {
+ 298 E("slram: No devicestart specified.\n");
+ 299 }
+ 300 T("slram: devstart = %s\n", devstart);
+ → 301 if ((!map) || (!(devlength = strsep(&map, ",")))) {
+ 302 E("slram: No devicelength / -end specified.\n");
+ 303 }
+ → 304 T("slram: devlength = %s\n", devlength);
+ 305 if (parse_cmdline(devname, devstart, devlength) != 0) {
+ 306 return(-EINVAL);
+ 307 }
+
+Parsing should be finished after map == NULL, so a break is best inserted after
+each E("slram: ... \n") error message.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: Miquel Raynal <miquel.raynal@bootlin.com>
+Cc: Richard Weinberger <richard@nod.at>
+Cc: Vignesh Raghavendra <vigneshr@ti.com>
+Cc: linux-mtd@lists.infradead.org
+Signed-off-by: Mirsad Todorovac <mtodorovac69@gmail.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20240711234319.637824-1-mtodorovac69@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/devices/slram.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
+index 28131a127d065..8297b366a0669 100644
+--- a/drivers/mtd/devices/slram.c
++++ b/drivers/mtd/devices/slram.c
+@@ -296,10 +296,12 @@ static int __init init_slram(void)
+ T("slram: devname = %s\n", devname);
+ if ((!map) || (!(devstart = strsep(&map, ",")))) {
+ E("slram: No devicestart specified.\n");
++ break;
+ }
+ T("slram: devstart = %s\n", devstart);
+ if ((!map) || (!(devlength = strsep(&map, ",")))) {
+ E("slram: No devicelength / -end specified.\n");
++ break;
+ }
+ T("slram: devlength = %s\n", devlength);
+ if (parse_cmdline(devname, devstart, devlength) != 0) {
+--
+2.43.0
+
--- /dev/null
+From 483d58742d61c11ff760ba05e08a6c425e8dd001 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Mar 2022 20:24:43 -0600
+Subject: net: axienet: add coalesce timer ethtool configuration
+
+From: Robert Hancock <robert.hancock@calian.com>
+
+[ Upstream commit 0b79b8dc97b9df4f873f63161e3050bafc4c4237 ]
+
+Add the ability to configure the RX/TX coalesce timer with ethtool.
+Change default setting to scale with the clock rate rather than being a
+fixed number of clock cycles.
+
+Signed-off-by: Robert Hancock <robert.hancock@calian.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 5a6caa2cfabb ("net: xilinx: axienet: Fix packet counting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/xilinx/xilinx_axienet.h | 10 ++--
+ .../net/ethernet/xilinx/xilinx_axienet_main.c | 51 +++++++++++++++----
+ 2 files changed, 47 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h
+index d2c17def082b4..8b3b414b00113 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet.h
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h
+@@ -119,11 +119,11 @@
+ #define XAXIDMA_IRQ_ERROR_MASK 0x00004000 /* Error interrupt */
+ #define XAXIDMA_IRQ_ALL_MASK 0x00007000 /* All interrupts */
+
+-/* Default TX/RX Threshold and waitbound values for SGDMA mode */
++/* Default TX/RX Threshold and delay timer values for SGDMA mode */
+ #define XAXIDMA_DFT_TX_THRESHOLD 24
+-#define XAXIDMA_DFT_TX_WAITBOUND 254
++#define XAXIDMA_DFT_TX_USEC 50
+ #define XAXIDMA_DFT_RX_THRESHOLD 1
+-#define XAXIDMA_DFT_RX_WAITBOUND 254
++#define XAXIDMA_DFT_RX_USEC 50
+
+ #define XAXIDMA_BD_CTRL_TXSOF_MASK 0x08000000 /* First tx packet */
+ #define XAXIDMA_BD_CTRL_TXEOF_MASK 0x04000000 /* Last tx packet */
+@@ -425,7 +425,9 @@ struct axidma_bd {
+ * @csum_offload_on_tx_path: Stores the checksum selection on TX side.
+ * @csum_offload_on_rx_path: Stores the checksum selection on RX side.
+ * @coalesce_count_rx: Store the irq coalesce on RX side.
++ * @coalesce_usec_rx: IRQ coalesce delay for RX
+ * @coalesce_count_tx: Store the irq coalesce on TX side.
++ * @coalesce_usec_tx: IRQ coalesce delay for TX
+ */
+ struct axienet_local {
+ struct net_device *ndev;
+@@ -481,7 +483,9 @@ struct axienet_local {
+ int csum_offload_on_rx_path;
+
+ u32 coalesce_count_rx;
++ u32 coalesce_usec_rx;
+ u32 coalesce_count_tx;
++ u32 coalesce_usec_tx;
+ };
+
+ /**
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+index a33e860861d55..fd5f7ac7f4a6b 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -33,7 +33,7 @@
+ #include <linux/of_irq.h>
+ #include <linux/of_address.h>
+ #include <linux/skbuff.h>
+-#include <linux/spinlock.h>
++#include <linux/math64.h>
+ #include <linux/phy.h>
+ #include <linux/mii.h>
+ #include <linux/ethtool.h>
+@@ -226,6 +226,28 @@ static void axienet_dma_bd_release(struct net_device *ndev)
+ lp->rx_bd_p);
+ }
+
++/**
++ * axienet_usec_to_timer - Calculate IRQ delay timer value
++ * @lp: Pointer to the axienet_local structure
++ * @coalesce_usec: Microseconds to convert into timer value
++ */
++static u32 axienet_usec_to_timer(struct axienet_local *lp, u32 coalesce_usec)
++{
++ u32 result;
++ u64 clk_rate = 125000000; /* arbitrary guess if no clock rate set */
++
++ if (lp->axi_clk)
++ clk_rate = clk_get_rate(lp->axi_clk);
++
++ /* 1 Timeout Interval = 125 * (clock period of SG clock) */
++ result = DIV64_U64_ROUND_CLOSEST((u64)coalesce_usec * clk_rate,
++ (u64)125000000);
++ if (result > 255)
++ result = 255;
++
++ return result;
++}
++
+ /**
+ * axienet_dma_start - Set up DMA registers and start DMA operation
+ * @lp: Pointer to the axienet_local structure
+@@ -241,7 +263,8 @@ static void axienet_dma_start(struct axienet_local *lp)
+ * the first RX packet. Otherwise leave at 0 to disable delay interrupt.
+ */
+ if (lp->coalesce_count_rx > 1)
+- lp->rx_dma_cr |= (XAXIDMA_DFT_RX_WAITBOUND << XAXIDMA_DELAY_SHIFT) |
++ lp->rx_dma_cr |= (axienet_usec_to_timer(lp, lp->coalesce_usec_rx)
++ << XAXIDMA_DELAY_SHIFT) |
+ XAXIDMA_IRQ_DELAY_MASK;
+ axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, lp->rx_dma_cr);
+
+@@ -252,7 +275,8 @@ static void axienet_dma_start(struct axienet_local *lp)
+ * the first TX packet. Otherwise leave at 0 to disable delay interrupt.
+ */
+ if (lp->coalesce_count_tx > 1)
+- tx_cr |= (XAXIDMA_DFT_TX_WAITBOUND << XAXIDMA_DELAY_SHIFT) |
++ tx_cr |= (axienet_usec_to_timer(lp, lp->coalesce_usec_tx)
++ << XAXIDMA_DELAY_SHIFT) |
+ XAXIDMA_IRQ_DELAY_MASK;
+ axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, tx_cr);
+
+@@ -1464,14 +1488,12 @@ axienet_ethtools_get_coalesce(struct net_device *ndev,
+ struct kernel_ethtool_coalesce *kernel_coal,
+ struct netlink_ext_ack *extack)
+ {
+- u32 regval = 0;
+ struct axienet_local *lp = netdev_priv(ndev);
+- regval = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
+- ecoalesce->rx_max_coalesced_frames = (regval & XAXIDMA_COALESCE_MASK)
+- >> XAXIDMA_COALESCE_SHIFT;
+- regval = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
+- ecoalesce->tx_max_coalesced_frames = (regval & XAXIDMA_COALESCE_MASK)
+- >> XAXIDMA_COALESCE_SHIFT;
++
++ ecoalesce->rx_max_coalesced_frames = lp->coalesce_count_rx;
++ ecoalesce->rx_coalesce_usecs = lp->coalesce_usec_rx;
++ ecoalesce->tx_max_coalesced_frames = lp->coalesce_count_tx;
++ ecoalesce->tx_coalesce_usecs = lp->coalesce_usec_tx;
+ return 0;
+ }
+
+@@ -1504,8 +1526,12 @@ axienet_ethtools_set_coalesce(struct net_device *ndev,
+
+ if (ecoalesce->rx_max_coalesced_frames)
+ lp->coalesce_count_rx = ecoalesce->rx_max_coalesced_frames;
++ if (ecoalesce->rx_coalesce_usecs)
++ lp->coalesce_usec_rx = ecoalesce->rx_coalesce_usecs;
+ if (ecoalesce->tx_max_coalesced_frames)
+ lp->coalesce_count_tx = ecoalesce->tx_max_coalesced_frames;
++ if (ecoalesce->tx_coalesce_usecs)
++ lp->coalesce_usec_tx = ecoalesce->tx_coalesce_usecs;
+
+ return 0;
+ }
+@@ -1536,7 +1562,8 @@ static int axienet_ethtools_nway_reset(struct net_device *dev)
+ }
+
+ static const struct ethtool_ops axienet_ethtool_ops = {
+- .supported_coalesce_params = ETHTOOL_COALESCE_MAX_FRAMES,
++ .supported_coalesce_params = ETHTOOL_COALESCE_MAX_FRAMES |
++ ETHTOOL_COALESCE_USECS,
+ .get_drvinfo = axienet_ethtools_get_drvinfo,
+ .get_regs_len = axienet_ethtools_get_regs_len,
+ .get_regs = axienet_ethtools_get_regs,
+@@ -2091,7 +2118,9 @@ static int axienet_probe(struct platform_device *pdev)
+ }
+
+ lp->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD;
++ lp->coalesce_usec_rx = XAXIDMA_DFT_RX_USEC;
+ lp->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD;
++ lp->coalesce_usec_tx = XAXIDMA_DFT_TX_USEC;
+
+ ret = axienet_mdio_setup(lp);
+ if (ret)
+--
+2.43.0
+
--- /dev/null
+From cedb0d359fe4ad72661f95d04c9dbb2f8da3e227 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 May 2022 11:18:52 -0600
+Subject: net: axienet: Be more careful about updating tx_bd_tail
+
+From: Robert Hancock <robert.hancock@calian.com>
+
+[ Upstream commit f0cf4000f5867ec4325d19d32bd83cf583065667 ]
+
+The axienet_start_xmit function was updating the tx_bd_tail variable
+multiple times, with potential rollbacks on error or invalid
+intermediate positions, even though this variable is also used in the
+TX completion path. Use READ_ONCE where this variable is read and
+WRITE_ONCE where it is written to make this update more atomic, and
+move the write before the MMIO write to start the transfer, so it is
+protected by that implicit write barrier.
+
+Signed-off-by: Robert Hancock <robert.hancock@calian.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 5a6caa2cfabb ("net: xilinx: axienet: Fix packet counting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/xilinx/xilinx_axienet_main.c | 26 +++++++++++--------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+index fd5f7ac7f4a6b..bcecf4b7308c1 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -747,7 +747,8 @@ static inline int axienet_check_tx_bd_space(struct axienet_local *lp,
+
+ /* Ensure we see all descriptor updates from device or TX IRQ path */
+ rmb();
+- cur_p = &lp->tx_bd_v[(lp->tx_bd_tail + num_frag) % lp->tx_bd_num];
++ cur_p = &lp->tx_bd_v[(READ_ONCE(lp->tx_bd_tail) + num_frag) %
++ lp->tx_bd_num];
+ if (cur_p->cntrl)
+ return NETDEV_TX_BUSY;
+ return 0;
+@@ -808,12 +809,15 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ u32 csum_index_off;
+ skb_frag_t *frag;
+ dma_addr_t tail_p, phys;
++ u32 orig_tail_ptr, new_tail_ptr;
+ struct axienet_local *lp = netdev_priv(ndev);
+ struct axidma_bd *cur_p;
+- u32 orig_tail_ptr = lp->tx_bd_tail;
++
++ orig_tail_ptr = lp->tx_bd_tail;
++ new_tail_ptr = orig_tail_ptr;
+
+ num_frag = skb_shinfo(skb)->nr_frags;
+- cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
++ cur_p = &lp->tx_bd_v[orig_tail_ptr];
+
+ if (axienet_check_tx_bd_space(lp, num_frag + 1)) {
+ /* Should not happen as last start_xmit call should have
+@@ -853,9 +857,9 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ cur_p->cntrl = skb_headlen(skb) | XAXIDMA_BD_CTRL_TXSOF_MASK;
+
+ for (ii = 0; ii < num_frag; ii++) {
+- if (++lp->tx_bd_tail >= lp->tx_bd_num)
+- lp->tx_bd_tail = 0;
+- cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
++ if (++new_tail_ptr >= lp->tx_bd_num)
++ new_tail_ptr = 0;
++ cur_p = &lp->tx_bd_v[new_tail_ptr];
+ frag = &skb_shinfo(skb)->frags[ii];
+ phys = dma_map_single(lp->dev,
+ skb_frag_address(frag),
+@@ -867,8 +871,6 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ ndev->stats.tx_dropped++;
+ axienet_free_tx_chain(ndev, orig_tail_ptr, ii + 1,
+ NULL);
+- lp->tx_bd_tail = orig_tail_ptr;
+-
+ return NETDEV_TX_OK;
+ }
+ desc_set_phys_addr(lp, phys, cur_p);
+@@ -878,11 +880,13 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ cur_p->cntrl |= XAXIDMA_BD_CTRL_TXEOF_MASK;
+ cur_p->skb = skb;
+
+- tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail;
++ tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * new_tail_ptr;
++ if (++new_tail_ptr >= lp->tx_bd_num)
++ new_tail_ptr = 0;
++ WRITE_ONCE(lp->tx_bd_tail, new_tail_ptr);
++
+ /* Start the transfer */
+ axienet_dma_out_addr(lp, XAXIDMA_TX_TDESC_OFFSET, tail_p);
+- if (++lp->tx_bd_tail >= lp->tx_bd_num)
+- lp->tx_bd_tail = 0;
+
+ /* Stop queue if next transmit may not have space */
+ if (axienet_check_tx_bd_space(lp, MAX_SKB_FRAGS + 1)) {
+--
+2.43.0
+
--- /dev/null
+From 65c7ebc8a1f1250deb71770ea262bdbca14dd0fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Mar 2022 20:24:38 -0600
+Subject: net: axienet: Clean up device used for DMA calls
+
+From: Robert Hancock <robert.hancock@calian.com>
+
+[ Upstream commit 17882fd4256721451457ee57532bbae0cd5cacfe ]
+
+Instead of using lp->ndev.parent to find the correct device to use for
+DMA API calls, just use the dev attribute in the device structure.
+
+Signed-off-by: Robert Hancock <robert.hancock@calian.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 5a6caa2cfabb ("net: xilinx: axienet: Fix packet counting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/xilinx/xilinx_axienet_main.c | 32 +++++++++----------
+ 1 file changed, 16 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+index 0ca350faa4848..50738ef43fb42 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -190,7 +190,7 @@ static void axienet_dma_bd_release(struct net_device *ndev)
+ struct axienet_local *lp = netdev_priv(ndev);
+
+ /* If we end up here, tx_bd_v must have been DMA allocated. */
+- dma_free_coherent(ndev->dev.parent,
++ dma_free_coherent(lp->dev,
+ sizeof(*lp->tx_bd_v) * lp->tx_bd_num,
+ lp->tx_bd_v,
+ lp->tx_bd_p);
+@@ -215,12 +215,12 @@ static void axienet_dma_bd_release(struct net_device *ndev)
+ */
+ if (lp->rx_bd_v[i].cntrl) {
+ phys = desc_get_phys_addr(lp, &lp->rx_bd_v[i]);
+- dma_unmap_single(ndev->dev.parent, phys,
++ dma_unmap_single(lp->dev, phys,
+ lp->max_frm_size, DMA_FROM_DEVICE);
+ }
+ }
+
+- dma_free_coherent(ndev->dev.parent,
++ dma_free_coherent(lp->dev,
+ sizeof(*lp->rx_bd_v) * lp->rx_bd_num,
+ lp->rx_bd_v,
+ lp->rx_bd_p);
+@@ -249,13 +249,13 @@ static int axienet_dma_bd_init(struct net_device *ndev)
+ lp->rx_bd_ci = 0;
+
+ /* Allocate the Tx and Rx buffer descriptors. */
+- lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent,
++ lp->tx_bd_v = dma_alloc_coherent(lp->dev,
+ sizeof(*lp->tx_bd_v) * lp->tx_bd_num,
+ &lp->tx_bd_p, GFP_KERNEL);
+ if (!lp->tx_bd_v)
+ return -ENOMEM;
+
+- lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent,
++ lp->rx_bd_v = dma_alloc_coherent(lp->dev,
+ sizeof(*lp->rx_bd_v) * lp->rx_bd_num,
+ &lp->rx_bd_p, GFP_KERNEL);
+ if (!lp->rx_bd_v)
+@@ -285,9 +285,9 @@ static int axienet_dma_bd_init(struct net_device *ndev)
+ goto out;
+
+ lp->rx_bd_v[i].skb = skb;
+- addr = dma_map_single(ndev->dev.parent, skb->data,
++ addr = dma_map_single(lp->dev, skb->data,
+ lp->max_frm_size, DMA_FROM_DEVICE);
+- if (dma_mapping_error(ndev->dev.parent, addr)) {
++ if (dma_mapping_error(lp->dev, addr)) {
+ netdev_err(ndev, "DMA mapping error\n");
+ goto out;
+ }
+@@ -637,7 +637,7 @@ static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd,
+ /* Ensure we see complete descriptor update */
+ dma_rmb();
+ phys = desc_get_phys_addr(lp, cur_p);
+- dma_unmap_single(ndev->dev.parent, phys,
++ dma_unmap_single(lp->dev, phys,
+ (cur_p->cntrl & XAXIDMA_BD_CTRL_LENGTH_MASK),
+ DMA_TO_DEVICE);
+
+@@ -775,9 +775,9 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ cur_p->app0 |= 2; /* Tx Full Checksum Offload Enabled */
+ }
+
+- phys = dma_map_single(ndev->dev.parent, skb->data,
++ phys = dma_map_single(lp->dev, skb->data,
+ skb_headlen(skb), DMA_TO_DEVICE);
+- if (unlikely(dma_mapping_error(ndev->dev.parent, phys))) {
++ if (unlikely(dma_mapping_error(lp->dev, phys))) {
+ if (net_ratelimit())
+ netdev_err(ndev, "TX DMA mapping error\n");
+ ndev->stats.tx_dropped++;
+@@ -791,11 +791,11 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ lp->tx_bd_tail = 0;
+ cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
+ frag = &skb_shinfo(skb)->frags[ii];
+- phys = dma_map_single(ndev->dev.parent,
++ phys = dma_map_single(lp->dev,
+ skb_frag_address(frag),
+ skb_frag_size(frag),
+ DMA_TO_DEVICE);
+- if (unlikely(dma_mapping_error(ndev->dev.parent, phys))) {
++ if (unlikely(dma_mapping_error(lp->dev, phys))) {
+ if (net_ratelimit())
+ netdev_err(ndev, "TX DMA mapping error\n");
+ ndev->stats.tx_dropped++;
+@@ -873,7 +873,7 @@ static void axienet_recv(struct net_device *ndev)
+ length = cur_p->app4 & 0x0000FFFF;
+
+ phys = desc_get_phys_addr(lp, cur_p);
+- dma_unmap_single(ndev->dev.parent, phys, lp->max_frm_size,
++ dma_unmap_single(lp->dev, phys, lp->max_frm_size,
+ DMA_FROM_DEVICE);
+
+ skb_put(skb, length);
+@@ -906,10 +906,10 @@ static void axienet_recv(struct net_device *ndev)
+ if (!new_skb)
+ break;
+
+- phys = dma_map_single(ndev->dev.parent, new_skb->data,
++ phys = dma_map_single(lp->dev, new_skb->data,
+ lp->max_frm_size,
+ DMA_FROM_DEVICE);
+- if (unlikely(dma_mapping_error(ndev->dev.parent, phys))) {
++ if (unlikely(dma_mapping_error(lp->dev, phys))) {
+ if (net_ratelimit())
+ netdev_err(ndev, "RX DMA mapping error\n");
+ dev_kfree_skb(new_skb);
+@@ -1770,7 +1770,7 @@ static void axienet_dma_err_handler(struct work_struct *work)
+ if (cur_p->cntrl) {
+ dma_addr_t addr = desc_get_phys_addr(lp, cur_p);
+
+- dma_unmap_single(ndev->dev.parent, addr,
++ dma_unmap_single(lp->dev, addr,
+ (cur_p->cntrl &
+ XAXIDMA_BD_CTRL_LENGTH_MASK),
+ DMA_TO_DEVICE);
+--
+2.43.0
+
--- /dev/null
+From 1b70217c7845c9842ffd458586c77e84f01424de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Mar 2022 20:24:39 -0600
+Subject: net: axienet: Clean up DMA start/stop and error handling
+
+From: Robert Hancock <robert.hancock@calian.com>
+
+[ Upstream commit 84b9ccc0749a7036bcaf707f02273dcbd4756fbf ]
+
+Simplify the DMA error handling process, and remove some duplicated code
+between the DMA error handling and the stop function.
+
+Signed-off-by: Robert Hancock <robert.hancock@calian.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 5a6caa2cfabb ("net: xilinx: axienet: Fix packet counting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/xilinx/xilinx_axienet_main.c | 280 +++++++-----------
+ 1 file changed, 105 insertions(+), 175 deletions(-)
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+index 50738ef43fb42..25b5054ad3e9b 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -226,6 +226,44 @@ static void axienet_dma_bd_release(struct net_device *ndev)
+ lp->rx_bd_p);
+ }
+
++/**
++ * axienet_dma_start - Set up DMA registers and start DMA operation
++ * @lp: Pointer to the axienet_local structure
++ */
++static void axienet_dma_start(struct axienet_local *lp)
++{
++ u32 rx_cr, tx_cr;
++
++ /* Start updating the Rx channel control register */
++ rx_cr = (lp->coalesce_count_rx << XAXIDMA_COALESCE_SHIFT) |
++ (XAXIDMA_DFT_RX_WAITBOUND << XAXIDMA_DELAY_SHIFT) |
++ XAXIDMA_IRQ_ALL_MASK;
++ axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, rx_cr);
++
++ /* Start updating the Tx channel control register */
++ tx_cr = (lp->coalesce_count_tx << XAXIDMA_COALESCE_SHIFT) |
++ (XAXIDMA_DFT_TX_WAITBOUND << XAXIDMA_DELAY_SHIFT) |
++ XAXIDMA_IRQ_ALL_MASK;
++ axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, tx_cr);
++
++ /* Populate the tail pointer and bring the Rx Axi DMA engine out of
++ * halted state. This will make the Rx side ready for reception.
++ */
++ axienet_dma_out_addr(lp, XAXIDMA_RX_CDESC_OFFSET, lp->rx_bd_p);
++ rx_cr |= XAXIDMA_CR_RUNSTOP_MASK;
++ axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, rx_cr);
++ axienet_dma_out_addr(lp, XAXIDMA_RX_TDESC_OFFSET, lp->rx_bd_p +
++ (sizeof(*lp->rx_bd_v) * (lp->rx_bd_num - 1)));
++
++ /* Write to the RS (Run-stop) bit in the Tx channel control register.
++ * Tx channel is now ready to run. But only after we write to the
++ * tail pointer register that the Tx channel will start transmitting.
++ */
++ axienet_dma_out_addr(lp, XAXIDMA_TX_CDESC_OFFSET, lp->tx_bd_p);
++ tx_cr |= XAXIDMA_CR_RUNSTOP_MASK;
++ axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, tx_cr);
++}
++
+ /**
+ * axienet_dma_bd_init - Setup buffer descriptor rings for Axi DMA
+ * @ndev: Pointer to the net_device structure
+@@ -238,7 +276,6 @@ static void axienet_dma_bd_release(struct net_device *ndev)
+ */
+ static int axienet_dma_bd_init(struct net_device *ndev)
+ {
+- u32 cr;
+ int i;
+ struct sk_buff *skb;
+ struct axienet_local *lp = netdev_priv(ndev);
+@@ -296,50 +333,7 @@ static int axienet_dma_bd_init(struct net_device *ndev)
+ lp->rx_bd_v[i].cntrl = lp->max_frm_size;
+ }
+
+- /* Start updating the Rx channel control register */
+- cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
+- /* Update the interrupt coalesce count */
+- cr = ((cr & ~XAXIDMA_COALESCE_MASK) |
+- ((lp->coalesce_count_rx) << XAXIDMA_COALESCE_SHIFT));
+- /* Update the delay timer count */
+- cr = ((cr & ~XAXIDMA_DELAY_MASK) |
+- (XAXIDMA_DFT_RX_WAITBOUND << XAXIDMA_DELAY_SHIFT));
+- /* Enable coalesce, delay timer and error interrupts */
+- cr |= XAXIDMA_IRQ_ALL_MASK;
+- /* Write to the Rx channel control register */
+- axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr);
+-
+- /* Start updating the Tx channel control register */
+- cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
+- /* Update the interrupt coalesce count */
+- cr = (((cr & ~XAXIDMA_COALESCE_MASK)) |
+- ((lp->coalesce_count_tx) << XAXIDMA_COALESCE_SHIFT));
+- /* Update the delay timer count */
+- cr = (((cr & ~XAXIDMA_DELAY_MASK)) |
+- (XAXIDMA_DFT_TX_WAITBOUND << XAXIDMA_DELAY_SHIFT));
+- /* Enable coalesce, delay timer and error interrupts */
+- cr |= XAXIDMA_IRQ_ALL_MASK;
+- /* Write to the Tx channel control register */
+- axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr);
+-
+- /* Populate the tail pointer and bring the Rx Axi DMA engine out of
+- * halted state. This will make the Rx side ready for reception.
+- */
+- axienet_dma_out_addr(lp, XAXIDMA_RX_CDESC_OFFSET, lp->rx_bd_p);
+- cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
+- axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET,
+- cr | XAXIDMA_CR_RUNSTOP_MASK);
+- axienet_dma_out_addr(lp, XAXIDMA_RX_TDESC_OFFSET, lp->rx_bd_p +
+- (sizeof(*lp->rx_bd_v) * (lp->rx_bd_num - 1)));
+-
+- /* Write to the RS (Run-stop) bit in the Tx channel control register.
+- * Tx channel is now ready to run. But only after we write to the
+- * tail pointer register that the Tx channel will start transmitting.
+- */
+- axienet_dma_out_addr(lp, XAXIDMA_TX_CDESC_OFFSET, lp->tx_bd_p);
+- cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
+- axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET,
+- cr | XAXIDMA_CR_RUNSTOP_MASK);
++ axienet_dma_start(lp);
+
+ return 0;
+ out:
+@@ -531,6 +525,44 @@ static int __axienet_device_reset(struct axienet_local *lp)
+ return 0;
+ }
+
++/**
++ * axienet_dma_stop - Stop DMA operation
++ * @lp: Pointer to the axienet_local structure
++ */
++static void axienet_dma_stop(struct axienet_local *lp)
++{
++ int count;
++ u32 cr, sr;
++
++ cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
++ cr &= ~(XAXIDMA_CR_RUNSTOP_MASK | XAXIDMA_IRQ_ALL_MASK);
++ axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr);
++ synchronize_irq(lp->rx_irq);
++
++ cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
++ cr &= ~(XAXIDMA_CR_RUNSTOP_MASK | XAXIDMA_IRQ_ALL_MASK);
++ axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr);
++ synchronize_irq(lp->tx_irq);
++
++ /* Give DMAs a chance to halt gracefully */
++ sr = axienet_dma_in32(lp, XAXIDMA_RX_SR_OFFSET);
++ for (count = 0; !(sr & XAXIDMA_SR_HALT_MASK) && count < 5; ++count) {
++ msleep(20);
++ sr = axienet_dma_in32(lp, XAXIDMA_RX_SR_OFFSET);
++ }
++
++ sr = axienet_dma_in32(lp, XAXIDMA_TX_SR_OFFSET);
++ for (count = 0; !(sr & XAXIDMA_SR_HALT_MASK) && count < 5; ++count) {
++ msleep(20);
++ sr = axienet_dma_in32(lp, XAXIDMA_TX_SR_OFFSET);
++ }
++
++ /* Do a reset to ensure DMA is really stopped */
++ axienet_lock_mii(lp);
++ __axienet_device_reset(lp);
++ axienet_unlock_mii(lp);
++}
++
+ /**
+ * axienet_device_reset - Reset and initialize the Axi Ethernet hardware.
+ * @ndev: Pointer to the net_device structure
+@@ -950,41 +982,27 @@ static void axienet_recv(struct net_device *ndev)
+ */
+ static irqreturn_t axienet_tx_irq(int irq, void *_ndev)
+ {
+- u32 cr;
+ unsigned int status;
+ struct net_device *ndev = _ndev;
+ struct axienet_local *lp = netdev_priv(ndev);
+
+ status = axienet_dma_in32(lp, XAXIDMA_TX_SR_OFFSET);
+- if (status & (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_DELAY_MASK)) {
+- axienet_dma_out32(lp, XAXIDMA_TX_SR_OFFSET, status);
+- axienet_start_xmit_done(lp->ndev);
+- goto out;
+- }
++
+ if (!(status & XAXIDMA_IRQ_ALL_MASK))
+ return IRQ_NONE;
+- if (status & XAXIDMA_IRQ_ERROR_MASK) {
+- dev_err(&ndev->dev, "DMA Tx error 0x%x\n", status);
+- dev_err(&ndev->dev, "Current BD is at: 0x%x%08x\n",
+- (lp->tx_bd_v[lp->tx_bd_ci]).phys_msb,
+- (lp->tx_bd_v[lp->tx_bd_ci]).phys);
+-
+- cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
+- /* Disable coalesce, delay timer and error interrupts */
+- cr &= (~XAXIDMA_IRQ_ALL_MASK);
+- /* Write to the Tx channel control register */
+- axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr);
+-
+- cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
+- /* Disable coalesce, delay timer and error interrupts */
+- cr &= (~XAXIDMA_IRQ_ALL_MASK);
+- /* Write to the Rx channel control register */
+- axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr);
+
++ axienet_dma_out32(lp, XAXIDMA_TX_SR_OFFSET, status);
++
++ if (unlikely(status & XAXIDMA_IRQ_ERROR_MASK)) {
++ netdev_err(ndev, "DMA Tx error 0x%x\n", status);
++ netdev_err(ndev, "Current BD is at: 0x%x%08x\n",
++ (lp->tx_bd_v[lp->tx_bd_ci]).phys_msb,
++ (lp->tx_bd_v[lp->tx_bd_ci]).phys);
+ schedule_work(&lp->dma_err_task);
+- axienet_dma_out32(lp, XAXIDMA_TX_SR_OFFSET, status);
++ } else {
++ axienet_start_xmit_done(lp->ndev);
+ }
+-out:
++
+ return IRQ_HANDLED;
+ }
+
+@@ -1000,41 +1018,27 @@ static irqreturn_t axienet_tx_irq(int irq, void *_ndev)
+ */
+ static irqreturn_t axienet_rx_irq(int irq, void *_ndev)
+ {
+- u32 cr;
+ unsigned int status;
+ struct net_device *ndev = _ndev;
+ struct axienet_local *lp = netdev_priv(ndev);
+
+ status = axienet_dma_in32(lp, XAXIDMA_RX_SR_OFFSET);
+- if (status & (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_DELAY_MASK)) {
+- axienet_dma_out32(lp, XAXIDMA_RX_SR_OFFSET, status);
+- axienet_recv(lp->ndev);
+- goto out;
+- }
++
+ if (!(status & XAXIDMA_IRQ_ALL_MASK))
+ return IRQ_NONE;
+- if (status & XAXIDMA_IRQ_ERROR_MASK) {
+- dev_err(&ndev->dev, "DMA Rx error 0x%x\n", status);
+- dev_err(&ndev->dev, "Current BD is at: 0x%x%08x\n",
+- (lp->rx_bd_v[lp->rx_bd_ci]).phys_msb,
+- (lp->rx_bd_v[lp->rx_bd_ci]).phys);
+-
+- cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
+- /* Disable coalesce, delay timer and error interrupts */
+- cr &= (~XAXIDMA_IRQ_ALL_MASK);
+- /* Finally write to the Tx channel control register */
+- axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr);
+-
+- cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
+- /* Disable coalesce, delay timer and error interrupts */
+- cr &= (~XAXIDMA_IRQ_ALL_MASK);
+- /* write to the Rx channel control register */
+- axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr);
+
++ axienet_dma_out32(lp, XAXIDMA_RX_SR_OFFSET, status);
++
++ if (unlikely(status & XAXIDMA_IRQ_ERROR_MASK)) {
++ netdev_err(ndev, "DMA Rx error 0x%x\n", status);
++ netdev_err(ndev, "Current BD is at: 0x%x%08x\n",
++ (lp->rx_bd_v[lp->rx_bd_ci]).phys_msb,
++ (lp->rx_bd_v[lp->rx_bd_ci]).phys);
+ schedule_work(&lp->dma_err_task);
+- axienet_dma_out32(lp, XAXIDMA_RX_SR_OFFSET, status);
++ } else {
++ axienet_recv(lp->ndev);
+ }
+-out:
++
+ return IRQ_HANDLED;
+ }
+
+@@ -1152,8 +1156,6 @@ static int axienet_open(struct net_device *ndev)
+ */
+ static int axienet_stop(struct net_device *ndev)
+ {
+- u32 cr, sr;
+- int count;
+ struct axienet_local *lp = netdev_priv(ndev);
+
+ dev_dbg(&ndev->dev, "axienet_close()\n");
+@@ -1164,34 +1166,10 @@ static int axienet_stop(struct net_device *ndev)
+ axienet_setoptions(ndev, lp->options &
+ ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN));
+
+- cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
+- cr &= ~(XAXIDMA_CR_RUNSTOP_MASK | XAXIDMA_IRQ_ALL_MASK);
+- axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr);
+-
+- cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
+- cr &= ~(XAXIDMA_CR_RUNSTOP_MASK | XAXIDMA_IRQ_ALL_MASK);
+- axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr);
++ axienet_dma_stop(lp);
+
+ axienet_iow(lp, XAE_IE_OFFSET, 0);
+
+- /* Give DMAs a chance to halt gracefully */
+- sr = axienet_dma_in32(lp, XAXIDMA_RX_SR_OFFSET);
+- for (count = 0; !(sr & XAXIDMA_SR_HALT_MASK) && count < 5; ++count) {
+- msleep(20);
+- sr = axienet_dma_in32(lp, XAXIDMA_RX_SR_OFFSET);
+- }
+-
+- sr = axienet_dma_in32(lp, XAXIDMA_TX_SR_OFFSET);
+- for (count = 0; !(sr & XAXIDMA_SR_HALT_MASK) && count < 5; ++count) {
+- msleep(20);
+- sr = axienet_dma_in32(lp, XAXIDMA_TX_SR_OFFSET);
+- }
+-
+- /* Do a reset to ensure DMA is really stopped */
+- axienet_lock_mii(lp);
+- __axienet_device_reset(lp);
+- axienet_unlock_mii(lp);
+-
+ cancel_work_sync(&lp->dma_err_task);
+
+ if (lp->eth_irq > 0)
+@@ -1748,22 +1726,17 @@ static const struct phylink_mac_ops axienet_phylink_ops = {
+ */
+ static void axienet_dma_err_handler(struct work_struct *work)
+ {
++ u32 i;
+ u32 axienet_status;
+- u32 cr, i;
++ struct axidma_bd *cur_p;
+ struct axienet_local *lp = container_of(work, struct axienet_local,
+ dma_err_task);
+ struct net_device *ndev = lp->ndev;
+- struct axidma_bd *cur_p;
+
+ axienet_setoptions(ndev, lp->options &
+ ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN));
+- /* When we do an Axi Ethernet reset, it resets the complete core
+- * including the MDIO. MDIO must be disabled before resetting.
+- * Hold MDIO bus lock to avoid MDIO accesses during the reset.
+- */
+- axienet_lock_mii(lp);
+- __axienet_device_reset(lp);
+- axienet_unlock_mii(lp);
++
++ axienet_dma_stop(lp);
+
+ for (i = 0; i < lp->tx_bd_num; i++) {
+ cur_p = &lp->tx_bd_v[i];
+@@ -1803,50 +1776,7 @@ static void axienet_dma_err_handler(struct work_struct *work)
+ lp->tx_bd_tail = 0;
+ lp->rx_bd_ci = 0;
+
+- /* Start updating the Rx channel control register */
+- cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
+- /* Update the interrupt coalesce count */
+- cr = ((cr & ~XAXIDMA_COALESCE_MASK) |
+- (XAXIDMA_DFT_RX_THRESHOLD << XAXIDMA_COALESCE_SHIFT));
+- /* Update the delay timer count */
+- cr = ((cr & ~XAXIDMA_DELAY_MASK) |
+- (XAXIDMA_DFT_RX_WAITBOUND << XAXIDMA_DELAY_SHIFT));
+- /* Enable coalesce, delay timer and error interrupts */
+- cr |= XAXIDMA_IRQ_ALL_MASK;
+- /* Finally write to the Rx channel control register */
+- axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr);
+-
+- /* Start updating the Tx channel control register */
+- cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
+- /* Update the interrupt coalesce count */
+- cr = (((cr & ~XAXIDMA_COALESCE_MASK)) |
+- (XAXIDMA_DFT_TX_THRESHOLD << XAXIDMA_COALESCE_SHIFT));
+- /* Update the delay timer count */
+- cr = (((cr & ~XAXIDMA_DELAY_MASK)) |
+- (XAXIDMA_DFT_TX_WAITBOUND << XAXIDMA_DELAY_SHIFT));
+- /* Enable coalesce, delay timer and error interrupts */
+- cr |= XAXIDMA_IRQ_ALL_MASK;
+- /* Finally write to the Tx channel control register */
+- axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr);
+-
+- /* Populate the tail pointer and bring the Rx Axi DMA engine out of
+- * halted state. This will make the Rx side ready for reception.
+- */
+- axienet_dma_out_addr(lp, XAXIDMA_RX_CDESC_OFFSET, lp->rx_bd_p);
+- cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
+- axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET,
+- cr | XAXIDMA_CR_RUNSTOP_MASK);
+- axienet_dma_out_addr(lp, XAXIDMA_RX_TDESC_OFFSET, lp->rx_bd_p +
+- (sizeof(*lp->rx_bd_v) * (lp->rx_bd_num - 1)));
+-
+- /* Write to the RS (Run-stop) bit in the Tx channel control register.
+- * Tx channel is now ready to run. But only after we write to the
+- * tail pointer register that the Tx channel will start transmitting
+- */
+- axienet_dma_out_addr(lp, XAXIDMA_TX_CDESC_OFFSET, lp->tx_bd_p);
+- cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
+- axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET,
+- cr | XAXIDMA_CR_RUNSTOP_MASK);
++ axienet_dma_start(lp);
+
+ axienet_status = axienet_ior(lp, XAE_RCW1_OFFSET);
+ axienet_status &= ~XAE_RCW1_RX_MASK;
+--
+2.43.0
+
--- /dev/null
+From cc3bfe5a7f7ec0fbab6dbfb49b1bd1029e8c9344 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Mar 2022 20:24:40 -0600
+Subject: net: axienet: don't set IRQ timer when IRQ delay not used
+
+From: Robert Hancock <robert.hancock@calian.com>
+
+[ Upstream commit 0155ae6eb84dbeecb7199a2fd9dee72e046ac875 ]
+
+When the RX or TX coalesce count is set to 1, there's no point in
+setting the delay timer value since an interrupt will already be raised
+on every packet, and the delay interrupt just causes extra pointless
+interrupts.
+
+Signed-off-by: Robert Hancock <robert.hancock@calian.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 5a6caa2cfabb ("net: xilinx: axienet: Fix packet counting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/xilinx/xilinx_axienet_main.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+index 25b5054ad3e9b..7bb8d04c997e7 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -236,14 +236,24 @@ static void axienet_dma_start(struct axienet_local *lp)
+
+ /* Start updating the Rx channel control register */
+ rx_cr = (lp->coalesce_count_rx << XAXIDMA_COALESCE_SHIFT) |
+- (XAXIDMA_DFT_RX_WAITBOUND << XAXIDMA_DELAY_SHIFT) |
+- XAXIDMA_IRQ_ALL_MASK;
++ XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_ERROR_MASK;
++ /* Only set interrupt delay timer if not generating an interrupt on
++ * the first RX packet. Otherwise leave at 0 to disable delay interrupt.
++ */
++ if (lp->coalesce_count_rx > 1)
++ rx_cr |= (XAXIDMA_DFT_RX_WAITBOUND << XAXIDMA_DELAY_SHIFT) |
++ XAXIDMA_IRQ_DELAY_MASK;
+ axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, rx_cr);
+
+ /* Start updating the Tx channel control register */
+ tx_cr = (lp->coalesce_count_tx << XAXIDMA_COALESCE_SHIFT) |
+- (XAXIDMA_DFT_TX_WAITBOUND << XAXIDMA_DELAY_SHIFT) |
+- XAXIDMA_IRQ_ALL_MASK;
++ XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_ERROR_MASK;
++ /* Only set interrupt delay timer if not generating an interrupt on
++ * the first TX packet. Otherwise leave at 0 to disable delay interrupt.
++ */
++ if (lp->coalesce_count_tx > 1)
++ tx_cr |= (XAXIDMA_DFT_TX_WAITBOUND << XAXIDMA_DELAY_SHIFT) |
++ XAXIDMA_IRQ_DELAY_MASK;
+ axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, tx_cr);
+
+ /* Populate the tail pointer and bring the Rx Axi DMA engine out of
+--
+2.43.0
+
--- /dev/null
+From 3318e8d776e31680792d84ff63fc8a1c24481c09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Mar 2022 20:24:41 -0600
+Subject: net: axienet: implement NAPI and GRO receive
+
+From: Robert Hancock <robert.hancock@calian.com>
+
+[ Upstream commit cc37610caaf8d13a6ecb8afd1fe2ebc2424ff622 ]
+
+Implement NAPI and GRO receive. In addition to better performance, this
+also avoids handling RX packets in hard IRQ context, which reduces the
+IRQ latency impact to other devices.
+
+Signed-off-by: Robert Hancock <robert.hancock@calian.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 5a6caa2cfabb ("net: xilinx: axienet: Fix packet counting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/xilinx/xilinx_axienet.h | 6 ++
+ .../net/ethernet/xilinx/xilinx_axienet_main.c | 81 ++++++++++++-------
+ 2 files changed, 59 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h
+index bdda836115095..e8a210201f744 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet.h
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h
+@@ -386,6 +386,7 @@ struct axidma_bd {
+ * @phy_node: Pointer to device node structure
+ * @phylink: Pointer to phylink instance
+ * @phylink_config: phylink configuration settings
++ * @napi: NAPI control structure
+ * @pcs_phy: Reference to PCS/PMA PHY if used
+ * @switch_x_sgmii: Whether switchable 1000BaseX/SGMII mode is enabled in the core
+ * @axi_clk: AXI4-Lite bus clock
+@@ -395,6 +396,7 @@ struct axidma_bd {
+ * @regs_start: Resource start for axienet device addresses
+ * @regs: Base address for the axienet_local device address space
+ * @dma_regs: Base address for the axidma device address space
++ * @rx_dma_cr: Nominal content of RX DMA control register
+ * @dma_err_task: Work structure to process Axi DMA errors
+ * @tx_irq: Axidma TX IRQ number
+ * @rx_irq: Axidma RX IRQ number
+@@ -434,6 +436,8 @@ struct axienet_local {
+ struct phylink *phylink;
+ struct phylink_config phylink_config;
+
++ struct napi_struct napi;
++
+ struct mdio_device *pcs_phy;
+
+ bool switch_x_sgmii;
+@@ -448,6 +452,8 @@ struct axienet_local {
+ void __iomem *regs;
+ void __iomem *dma_regs;
+
++ u32 rx_dma_cr;
++
+ struct work_struct dma_err_task;
+
+ int tx_irq;
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+index 7bb8d04c997e7..a33e860861d55 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -7,7 +7,7 @@
+ * Copyright (c) 2008-2009 Secret Lab Technologies Ltd.
+ * Copyright (c) 2010 - 2011 Michal Simek <monstr@monstr.eu>
+ * Copyright (c) 2010 - 2011 PetaLogix
+- * Copyright (c) 2019 SED Systems, a division of Calian Ltd.
++ * Copyright (c) 2019 - 2022 Calian Advanced Technologies
+ * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved.
+ *
+ * This is a driver for the Xilinx Axi Ethernet which is used in the Virtex6
+@@ -232,18 +232,18 @@ static void axienet_dma_bd_release(struct net_device *ndev)
+ */
+ static void axienet_dma_start(struct axienet_local *lp)
+ {
+- u32 rx_cr, tx_cr;
++ u32 tx_cr;
+
+ /* Start updating the Rx channel control register */
+- rx_cr = (lp->coalesce_count_rx << XAXIDMA_COALESCE_SHIFT) |
+- XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_ERROR_MASK;
++ lp->rx_dma_cr = (lp->coalesce_count_rx << XAXIDMA_COALESCE_SHIFT) |
++ XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_ERROR_MASK;
+ /* Only set interrupt delay timer if not generating an interrupt on
+ * the first RX packet. Otherwise leave at 0 to disable delay interrupt.
+ */
+ if (lp->coalesce_count_rx > 1)
+- rx_cr |= (XAXIDMA_DFT_RX_WAITBOUND << XAXIDMA_DELAY_SHIFT) |
+- XAXIDMA_IRQ_DELAY_MASK;
+- axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, rx_cr);
++ lp->rx_dma_cr |= (XAXIDMA_DFT_RX_WAITBOUND << XAXIDMA_DELAY_SHIFT) |
++ XAXIDMA_IRQ_DELAY_MASK;
++ axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, lp->rx_dma_cr);
+
+ /* Start updating the Tx channel control register */
+ tx_cr = (lp->coalesce_count_tx << XAXIDMA_COALESCE_SHIFT) |
+@@ -260,8 +260,8 @@ static void axienet_dma_start(struct axienet_local *lp)
+ * halted state. This will make the Rx side ready for reception.
+ */
+ axienet_dma_out_addr(lp, XAXIDMA_RX_CDESC_OFFSET, lp->rx_bd_p);
+- rx_cr |= XAXIDMA_CR_RUNSTOP_MASK;
+- axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, rx_cr);
++ lp->rx_dma_cr |= XAXIDMA_CR_RUNSTOP_MASK;
++ axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, lp->rx_dma_cr);
+ axienet_dma_out_addr(lp, XAXIDMA_RX_TDESC_OFFSET, lp->rx_bd_p +
+ (sizeof(*lp->rx_bd_v) * (lp->rx_bd_num - 1)));
+
+@@ -876,28 +876,26 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ }
+
+ /**
+- * axienet_recv - Is called from Axi DMA Rx Isr to complete the received
+- * BD processing.
+- * @ndev: Pointer to net_device structure.
++ * axienet_poll - Triggered by RX ISR to complete the received BD processing.
++ * @napi: Pointer to NAPI structure.
++ * @budget: Max number of packets to process.
+ *
+- * This function is invoked from the Axi DMA Rx isr to process the Rx BDs. It
+- * does minimal processing and invokes "netif_rx" to complete further
+- * processing.
++ * Return: Number of RX packets processed.
+ */
+-static void axienet_recv(struct net_device *ndev)
++static int axienet_poll(struct napi_struct *napi, int budget)
+ {
+ u32 length;
+ u32 csumstatus;
+ u32 size = 0;
+- u32 packets = 0;
++ int packets = 0;
+ dma_addr_t tail_p = 0;
+- struct axienet_local *lp = netdev_priv(ndev);
+- struct sk_buff *skb, *new_skb;
+ struct axidma_bd *cur_p;
++ struct sk_buff *skb, *new_skb;
++ struct axienet_local *lp = container_of(napi, struct axienet_local, napi);
+
+ cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
+
+- while ((cur_p->status & XAXIDMA_BD_STS_COMPLETE_MASK)) {
++ while (packets < budget && (cur_p->status & XAXIDMA_BD_STS_COMPLETE_MASK)) {
+ dma_addr_t phys;
+
+ /* Ensure we see complete descriptor update */
+@@ -919,7 +917,7 @@ static void axienet_recv(struct net_device *ndev)
+ DMA_FROM_DEVICE);
+
+ skb_put(skb, length);
+- skb->protocol = eth_type_trans(skb, ndev);
++ skb->protocol = eth_type_trans(skb, lp->ndev);
+ /*skb_checksum_none_assert(skb);*/
+ skb->ip_summed = CHECKSUM_NONE;
+
+@@ -938,13 +936,13 @@ static void axienet_recv(struct net_device *ndev)
+ skb->ip_summed = CHECKSUM_COMPLETE;
+ }
+
+- netif_rx(skb);
++ napi_gro_receive(napi, skb);
+
+ size += length;
+ packets++;
+ }
+
+- new_skb = netdev_alloc_skb_ip_align(ndev, lp->max_frm_size);
++ new_skb = netdev_alloc_skb_ip_align(lp->ndev, lp->max_frm_size);
+ if (!new_skb)
+ break;
+
+@@ -953,7 +951,7 @@ static void axienet_recv(struct net_device *ndev)
+ DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(lp->dev, phys))) {
+ if (net_ratelimit())
+- netdev_err(ndev, "RX DMA mapping error\n");
++ netdev_err(lp->ndev, "RX DMA mapping error\n");
+ dev_kfree_skb(new_skb);
+ break;
+ }
+@@ -973,11 +971,20 @@ static void axienet_recv(struct net_device *ndev)
+ cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
+ }
+
+- ndev->stats.rx_packets += packets;
+- ndev->stats.rx_bytes += size;
++ lp->ndev->stats.rx_packets += packets;
++ lp->ndev->stats.rx_bytes += size;
+
+ if (tail_p)
+ axienet_dma_out_addr(lp, XAXIDMA_RX_TDESC_OFFSET, tail_p);
++
++ if (packets < budget && napi_complete_done(napi, packets)) {
++ /* Re-enable RX completion interrupts. This should
++ * cause an immediate interrupt if any RX packets are
++ * already pending.
++ */
++ axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, lp->rx_dma_cr);
++ }
++ return packets;
+ }
+
+ /**
+@@ -1023,7 +1030,7 @@ static irqreturn_t axienet_tx_irq(int irq, void *_ndev)
+ *
+ * Return: IRQ_HANDLED if device generated a RX interrupt, IRQ_NONE otherwise.
+ *
+- * This is the Axi DMA Rx Isr. It invokes "axienet_recv" to complete the BD
++ * This is the Axi DMA Rx Isr. It invokes NAPI polling to complete the RX BD
+ * processing.
+ */
+ static irqreturn_t axienet_rx_irq(int irq, void *_ndev)
+@@ -1046,7 +1053,15 @@ static irqreturn_t axienet_rx_irq(int irq, void *_ndev)
+ (lp->rx_bd_v[lp->rx_bd_ci]).phys);
+ schedule_work(&lp->dma_err_task);
+ } else {
+- axienet_recv(lp->ndev);
++ /* Disable further RX completion interrupts and schedule
++ * NAPI receive.
++ */
++ u32 cr = lp->rx_dma_cr;
++
++ cr &= ~(XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_DELAY_MASK);
++ axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr);
++
++ napi_schedule(&lp->napi);
+ }
+
+ return IRQ_HANDLED;
+@@ -1122,6 +1137,8 @@ static int axienet_open(struct net_device *ndev)
+ /* Enable worker thread for Axi DMA error handling */
+ INIT_WORK(&lp->dma_err_task, axienet_dma_err_handler);
+
++ napi_enable(&lp->napi);
++
+ /* Enable interrupts for Axi DMA Tx */
+ ret = request_irq(lp->tx_irq, axienet_tx_irq, IRQF_SHARED,
+ ndev->name, ndev);
+@@ -1147,6 +1164,7 @@ static int axienet_open(struct net_device *ndev)
+ err_rx_irq:
+ free_irq(lp->tx_irq, ndev);
+ err_tx_irq:
++ napi_disable(&lp->napi);
+ phylink_stop(lp->phylink);
+ phylink_disconnect_phy(lp->phylink);
+ cancel_work_sync(&lp->dma_err_task);
+@@ -1170,6 +1188,8 @@ static int axienet_stop(struct net_device *ndev)
+
+ dev_dbg(&ndev->dev, "axienet_close()\n");
+
++ napi_disable(&lp->napi);
++
+ phylink_stop(lp->phylink);
+ phylink_disconnect_phy(lp->phylink);
+
+@@ -1743,6 +1763,8 @@ static void axienet_dma_err_handler(struct work_struct *work)
+ dma_err_task);
+ struct net_device *ndev = lp->ndev;
+
++ napi_disable(&lp->napi);
++
+ axienet_setoptions(ndev, lp->options &
+ ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN));
+
+@@ -1807,6 +1829,7 @@ static void axienet_dma_err_handler(struct work_struct *work)
+ axienet_set_mac_address(ndev, NULL);
+ axienet_set_multicast_list(ndev);
+ axienet_setoptions(ndev, lp->options);
++ napi_enable(&lp->napi);
+ }
+
+ /**
+@@ -1855,6 +1878,8 @@ static int axienet_probe(struct platform_device *pdev)
+ lp->rx_bd_num = RX_BD_NUM_DEFAULT;
+ lp->tx_bd_num = TX_BD_NUM_DEFAULT;
+
++ netif_napi_add(ndev, &lp->napi, axienet_poll, NAPI_POLL_WEIGHT);
++
+ lp->axi_clk = devm_clk_get_optional(&pdev->dev, "s_axi_lite_clk");
+ if (!lp->axi_clk) {
+ /* For backward compatibility, if named AXI clock is not present,
+--
+2.43.0
+
--- /dev/null
+From 16f685785a50da07c61dbba5ac9af1773bed8f4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Mar 2022 20:24:42 -0600
+Subject: net: axienet: reduce default RX interrupt threshold to 1
+
+From: Robert Hancock <robert.hancock@calian.com>
+
+[ Upstream commit 40da5d680e02ca8d61237192db4b5833d3c9639f ]
+
+Now that NAPI has been implemented, the hardware interrupt mitigation
+mechanism is not needed to avoid excessive interrupt load in most cases.
+Reduce the default RX interrupt threshold to 1 to reduce introduced
+latency. This can be increased with ethtool if desired if some applications
+still want to reduce interrupts.
+
+Signed-off-by: Robert Hancock <robert.hancock@calian.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 5a6caa2cfabb ("net: xilinx: axienet: Fix packet counting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/xilinx/xilinx_axienet.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h
+index e8a210201f744..d2c17def082b4 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet.h
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h
+@@ -122,7 +122,7 @@
+ /* Default TX/RX Threshold and waitbound values for SGDMA mode */
+ #define XAXIDMA_DFT_TX_THRESHOLD 24
+ #define XAXIDMA_DFT_TX_WAITBOUND 254
+-#define XAXIDMA_DFT_RX_THRESHOLD 24
++#define XAXIDMA_DFT_RX_THRESHOLD 1
+ #define XAXIDMA_DFT_RX_WAITBOUND 254
+
+ #define XAXIDMA_BD_CTRL_TXSOF_MASK 0x08000000 /* First tx packet */
+--
+2.43.0
+
--- /dev/null
+From 9fc8b2a01e395949d51b2bf2909d1832d1b49979 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Aug 2022 17:39:01 -0600
+Subject: net: axienet: Switch to 64-bit RX/TX statistics
+
+From: Robert Hancock <robert.hancock@calian.com>
+
+[ Upstream commit cb45a8bf4693965e89d115cd2c510f12bc127c37 ]
+
+The RX and TX byte/packet statistics in this driver could be overflowed
+relatively quickly on a 32-bit platform. Switch these stats to use the
+u64_stats infrastructure to avoid this.
+
+Signed-off-by: Robert Hancock <robert.hancock@calian.com>
+Link: https://lore.kernel.org/r/20220829233901.3429419-1-robert.hancock@calian.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 5a6caa2cfabb ("net: xilinx: axienet: Fix packet counting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/xilinx/xilinx_axienet.h | 12 ++++++
+ .../net/ethernet/xilinx/xilinx_axienet_main.c | 37 +++++++++++++++++--
+ 2 files changed, 45 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h
+index 7bf6b3def460f..54087ce1c07cd 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet.h
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h
+@@ -402,6 +402,9 @@ struct axidma_bd {
+ * @rx_bd_num: Size of RX buffer descriptor ring
+ * @rx_bd_ci: Stores the index of the Rx buffer descriptor in the ring being
+ * accessed currently.
++ * @rx_packets: RX packet count for statistics
++ * @rx_bytes: RX byte count for statistics
++ * @rx_stat_sync: Synchronization object for RX stats
+ * @napi_tx: NAPI TX control structure
+ * @tx_dma_cr: Nominal content of TX DMA control register
+ * @tx_bd_v: Virtual address of the TX buffer descriptor ring
+@@ -411,6 +414,9 @@ struct axidma_bd {
+ * complete. Only updated at runtime by TX NAPI poll.
+ * @tx_bd_tail: Stores the index of the next Tx buffer descriptor in the ring
+ * to be populated.
++ * @tx_packets: TX packet count for statistics
++ * @tx_bytes: TX byte count for statistics
++ * @tx_stat_sync: Synchronization object for TX stats
+ * @dma_err_task: Work structure to process Axi DMA errors
+ * @tx_irq: Axidma TX IRQ number
+ * @rx_irq: Axidma RX IRQ number
+@@ -459,6 +465,9 @@ struct axienet_local {
+ dma_addr_t rx_bd_p;
+ u32 rx_bd_num;
+ u32 rx_bd_ci;
++ u64_stats_t rx_packets;
++ u64_stats_t rx_bytes;
++ struct u64_stats_sync rx_stat_sync;
+
+ struct napi_struct napi_tx;
+ u32 tx_dma_cr;
+@@ -467,6 +476,9 @@ struct axienet_local {
+ u32 tx_bd_num;
+ u32 tx_bd_ci;
+ u32 tx_bd_tail;
++ u64_stats_t tx_packets;
++ u64_stats_t tx_bytes;
++ struct u64_stats_sync tx_stat_sync;
+
+ struct work_struct dma_err_task;
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+index 356ae4139d262..9805b81bd490a 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -777,8 +777,10 @@ static int axienet_tx_poll(struct napi_struct *napi, int budget)
+ if (lp->tx_bd_ci >= lp->tx_bd_num)
+ lp->tx_bd_ci %= lp->tx_bd_num;
+
+- ndev->stats.tx_packets += packets;
+- ndev->stats.tx_bytes += size;
++ u64_stats_update_begin(&lp->tx_stat_sync);
++ u64_stats_add(&lp->tx_packets, packets);
++ u64_stats_add(&lp->tx_bytes, size);
++ u64_stats_update_end(&lp->tx_stat_sync);
+
+ /* Matches barrier in axienet_start_xmit */
+ smp_mb();
+@@ -1009,8 +1011,10 @@ static int axienet_rx_poll(struct napi_struct *napi, int budget)
+ cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
+ }
+
+- lp->ndev->stats.rx_packets += packets;
+- lp->ndev->stats.rx_bytes += size;
++ u64_stats_update_begin(&lp->rx_stat_sync);
++ u64_stats_add(&lp->rx_packets, packets);
++ u64_stats_add(&lp->rx_bytes, size);
++ u64_stats_update_end(&lp->rx_stat_sync);
+
+ if (tail_p)
+ axienet_dma_out_addr(lp, XAXIDMA_RX_TDESC_OFFSET, tail_p);
+@@ -1317,10 +1321,32 @@ static int axienet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+ return phylink_mii_ioctl(lp->phylink, rq, cmd);
+ }
+
++static void
++axienet_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
++{
++ struct axienet_local *lp = netdev_priv(dev);
++ unsigned int start;
++
++ netdev_stats_to_stats64(stats, &dev->stats);
++
++ do {
++ start = u64_stats_fetch_begin_irq(&lp->rx_stat_sync);
++ stats->rx_packets = u64_stats_read(&lp->rx_packets);
++ stats->rx_bytes = u64_stats_read(&lp->rx_bytes);
++ } while (u64_stats_fetch_retry_irq(&lp->rx_stat_sync, start));
++
++ do {
++ start = u64_stats_fetch_begin_irq(&lp->tx_stat_sync);
++ stats->tx_packets = u64_stats_read(&lp->tx_packets);
++ stats->tx_bytes = u64_stats_read(&lp->tx_bytes);
++ } while (u64_stats_fetch_retry_irq(&lp->tx_stat_sync, start));
++}
++
+ static const struct net_device_ops axienet_netdev_ops = {
+ .ndo_open = axienet_open,
+ .ndo_stop = axienet_stop,
+ .ndo_start_xmit = axienet_start_xmit,
++ .ndo_get_stats64 = axienet_get_stats64,
+ .ndo_change_mtu = axienet_change_mtu,
+ .ndo_set_mac_address = netdev_set_mac_address,
+ .ndo_validate_addr = eth_validate_addr,
+@@ -1932,6 +1958,9 @@ static int axienet_probe(struct platform_device *pdev)
+ lp->rx_bd_num = RX_BD_NUM_DEFAULT;
+ lp->tx_bd_num = TX_BD_NUM_DEFAULT;
+
++ u64_stats_init(&lp->rx_stat_sync);
++ u64_stats_init(&lp->tx_stat_sync);
++
+ netif_napi_add(ndev, &lp->napi_rx, axienet_rx_poll, NAPI_POLL_WEIGHT);
+ netif_napi_add(ndev, &lp->napi_tx, axienet_tx_poll, NAPI_POLL_WEIGHT);
+
+--
+2.43.0
+
--- /dev/null
+From abfca88934a4dc715cb1fb4027193f5151fef263 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 May 2022 11:18:53 -0600
+Subject: net: axienet: Use NAPI for TX completion path
+
+From: Robert Hancock <robert.hancock@calian.com>
+
+[ Upstream commit 9e2bc267e78068b512d4409b884662f425adb1ec ]
+
+This driver was using the TX IRQ handler to perform all TX completion
+tasks. Under heavy TX network load, this can cause significant irqs-off
+latencies (found to be in the hundreds of microseconds using ftrace).
+This can cause other issues, such as overrunning serial UART FIFOs when
+using high baud rates with limited UART FIFO sizes.
+
+Switch to using a NAPI poll handler to perform the TX completion work
+to get this out of hard IRQ context and avoid the IRQ latency impact.
+A separate poll handler is used for TX and RX since they have separate
+IRQs on this controller, so that the completion work for each of them
+stays on the same CPU as the interrupt.
+
+Testing on a Xilinx MPSoC ZU9EG platform using iperf3 from a Linux PC
+through a switch at 1G link speed showed no significant change in TX or
+RX throughput, with approximately 941 Mbps before and after. Hard IRQ
+time in the TX throughput test was significantly reduced from 12% to
+below 1% on the CPU handling TX interrupts, with total hard+soft IRQ CPU
+usage dropping from about 56% down to 48%.
+
+Signed-off-by: Robert Hancock <robert.hancock@calian.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 5a6caa2cfabb ("net: xilinx: axienet: Fix packet counting")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/xilinx/xilinx_axienet.h | 54 +++----
+ .../net/ethernet/xilinx/xilinx_axienet_main.c | 142 ++++++++++--------
+ 2 files changed, 111 insertions(+), 85 deletions(-)
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h
+index 8b3b414b00113..7bf6b3def460f 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet.h
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h
+@@ -386,7 +386,6 @@ struct axidma_bd {
+ * @phy_node: Pointer to device node structure
+ * @phylink: Pointer to phylink instance
+ * @phylink_config: phylink configuration settings
+- * @napi: NAPI control structure
+ * @pcs_phy: Reference to PCS/PMA PHY if used
+ * @switch_x_sgmii: Whether switchable 1000BaseX/SGMII mode is enabled in the core
+ * @axi_clk: AXI4-Lite bus clock
+@@ -396,7 +395,22 @@ struct axidma_bd {
+ * @regs_start: Resource start for axienet device addresses
+ * @regs: Base address for the axienet_local device address space
+ * @dma_regs: Base address for the axidma device address space
++ * @napi_rx: NAPI RX control structure
+ * @rx_dma_cr: Nominal content of RX DMA control register
++ * @rx_bd_v: Virtual address of the RX buffer descriptor ring
++ * @rx_bd_p: Physical address(start address) of the RX buffer descr. ring
++ * @rx_bd_num: Size of RX buffer descriptor ring
++ * @rx_bd_ci: Stores the index of the Rx buffer descriptor in the ring being
++ * accessed currently.
++ * @napi_tx: NAPI TX control structure
++ * @tx_dma_cr: Nominal content of TX DMA control register
++ * @tx_bd_v: Virtual address of the TX buffer descriptor ring
++ * @tx_bd_p: Physical address(start address) of the TX buffer descr. ring
++ * @tx_bd_num: Size of TX buffer descriptor ring
++ * @tx_bd_ci: Stores the next Tx buffer descriptor in the ring that may be
++ * complete. Only updated at runtime by TX NAPI poll.
++ * @tx_bd_tail: Stores the index of the next Tx buffer descriptor in the ring
++ * to be populated.
+ * @dma_err_task: Work structure to process Axi DMA errors
+ * @tx_irq: Axidma TX IRQ number
+ * @rx_irq: Axidma RX IRQ number
+@@ -404,19 +418,6 @@ struct axidma_bd {
+ * @phy_mode: Phy type to identify between MII/GMII/RGMII/SGMII/1000 Base-X
+ * @options: AxiEthernet option word
+ * @features: Stores the extended features supported by the axienet hw
+- * @tx_bd_v: Virtual address of the TX buffer descriptor ring
+- * @tx_bd_p: Physical address(start address) of the TX buffer descr. ring
+- * @tx_bd_num: Size of TX buffer descriptor ring
+- * @rx_bd_v: Virtual address of the RX buffer descriptor ring
+- * @rx_bd_p: Physical address(start address) of the RX buffer descr. ring
+- * @rx_bd_num: Size of RX buffer descriptor ring
+- * @tx_bd_ci: Stores the index of the Tx buffer descriptor in the ring being
+- * accessed currently. Used while alloc. BDs before a TX starts
+- * @tx_bd_tail: Stores the index of the Tx buffer descriptor in the ring being
+- * accessed currently. Used while processing BDs after the TX
+- * completed.
+- * @rx_bd_ci: Stores the index of the Rx buffer descriptor in the ring being
+- * accessed currently.
+ * @max_frm_size: Stores the maximum size of the frame that can be that
+ * Txed/Rxed in the existing hardware. If jumbo option is
+ * supported, the maximum frame size would be 9k. Else it is
+@@ -438,8 +439,6 @@ struct axienet_local {
+ struct phylink *phylink;
+ struct phylink_config phylink_config;
+
+- struct napi_struct napi;
+-
+ struct mdio_device *pcs_phy;
+
+ bool switch_x_sgmii;
+@@ -454,7 +453,20 @@ struct axienet_local {
+ void __iomem *regs;
+ void __iomem *dma_regs;
+
++ struct napi_struct napi_rx;
+ u32 rx_dma_cr;
++ struct axidma_bd *rx_bd_v;
++ dma_addr_t rx_bd_p;
++ u32 rx_bd_num;
++ u32 rx_bd_ci;
++
++ struct napi_struct napi_tx;
++ u32 tx_dma_cr;
++ struct axidma_bd *tx_bd_v;
++ dma_addr_t tx_bd_p;
++ u32 tx_bd_num;
++ u32 tx_bd_ci;
++ u32 tx_bd_tail;
+
+ struct work_struct dma_err_task;
+
+@@ -466,16 +478,6 @@ struct axienet_local {
+ u32 options;
+ u32 features;
+
+- struct axidma_bd *tx_bd_v;
+- dma_addr_t tx_bd_p;
+- u32 tx_bd_num;
+- struct axidma_bd *rx_bd_v;
+- dma_addr_t rx_bd_p;
+- u32 rx_bd_num;
+- u32 tx_bd_ci;
+- u32 tx_bd_tail;
+- u32 rx_bd_ci;
+-
+ u32 max_frm_size;
+ u32 rxmem;
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+index bcecf4b7308c1..356ae4139d262 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -254,8 +254,6 @@ static u32 axienet_usec_to_timer(struct axienet_local *lp, u32 coalesce_usec)
+ */
+ static void axienet_dma_start(struct axienet_local *lp)
+ {
+- u32 tx_cr;
+-
+ /* Start updating the Rx channel control register */
+ lp->rx_dma_cr = (lp->coalesce_count_rx << XAXIDMA_COALESCE_SHIFT) |
+ XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_ERROR_MASK;
+@@ -269,16 +267,16 @@ static void axienet_dma_start(struct axienet_local *lp)
+ axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, lp->rx_dma_cr);
+
+ /* Start updating the Tx channel control register */
+- tx_cr = (lp->coalesce_count_tx << XAXIDMA_COALESCE_SHIFT) |
+- XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_ERROR_MASK;
++ lp->tx_dma_cr = (lp->coalesce_count_tx << XAXIDMA_COALESCE_SHIFT) |
++ XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_ERROR_MASK;
+ /* Only set interrupt delay timer if not generating an interrupt on
+ * the first TX packet. Otherwise leave at 0 to disable delay interrupt.
+ */
+ if (lp->coalesce_count_tx > 1)
+- tx_cr |= (axienet_usec_to_timer(lp, lp->coalesce_usec_tx)
+- << XAXIDMA_DELAY_SHIFT) |
+- XAXIDMA_IRQ_DELAY_MASK;
+- axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, tx_cr);
++ lp->tx_dma_cr |= (axienet_usec_to_timer(lp, lp->coalesce_usec_tx)
++ << XAXIDMA_DELAY_SHIFT) |
++ XAXIDMA_IRQ_DELAY_MASK;
++ axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, lp->tx_dma_cr);
+
+ /* Populate the tail pointer and bring the Rx Axi DMA engine out of
+ * halted state. This will make the Rx side ready for reception.
+@@ -294,8 +292,8 @@ static void axienet_dma_start(struct axienet_local *lp)
+ * tail pointer register that the Tx channel will start transmitting.
+ */
+ axienet_dma_out_addr(lp, XAXIDMA_TX_CDESC_OFFSET, lp->tx_bd_p);
+- tx_cr |= XAXIDMA_CR_RUNSTOP_MASK;
+- axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, tx_cr);
++ lp->tx_dma_cr |= XAXIDMA_CR_RUNSTOP_MASK;
++ axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, lp->tx_dma_cr);
+ }
+
+ /**
+@@ -667,37 +665,34 @@ static int axienet_device_reset(struct net_device *ndev)
+
+ /**
+ * axienet_free_tx_chain - Clean up a series of linked TX descriptors.
+- * @ndev: Pointer to the net_device structure
++ * @lp: Pointer to the axienet_local structure
+ * @first_bd: Index of first descriptor to clean up
+- * @nr_bds: Number of descriptors to clean up, can be -1 if unknown.
++ * @nr_bds: Max number of descriptors to clean up
++ * @force: Whether to clean descriptors even if not complete
+ * @sizep: Pointer to a u32 filled with the total sum of all bytes
+ * in all cleaned-up descriptors. Ignored if NULL.
++ * @budget: NAPI budget (use 0 when not called from NAPI poll)
+ *
+ * Would either be called after a successful transmit operation, or after
+ * there was an error when setting up the chain.
+ * Returns the number of descriptors handled.
+ */
+-static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd,
+- int nr_bds, u32 *sizep)
++static int axienet_free_tx_chain(struct axienet_local *lp, u32 first_bd,
++ int nr_bds, bool force, u32 *sizep, int budget)
+ {
+- struct axienet_local *lp = netdev_priv(ndev);
+ struct axidma_bd *cur_p;
+- int max_bds = nr_bds;
+ unsigned int status;
+ dma_addr_t phys;
+ int i;
+
+- if (max_bds == -1)
+- max_bds = lp->tx_bd_num;
+-
+- for (i = 0; i < max_bds; i++) {
++ for (i = 0; i < nr_bds; i++) {
+ cur_p = &lp->tx_bd_v[(first_bd + i) % lp->tx_bd_num];
+ status = cur_p->status;
+
+- /* If no number is given, clean up *all* descriptors that have
+- * been completed by the MAC.
++ /* If force is not specified, clean up only descriptors
++ * that have been completed by the MAC.
+ */
+- if (nr_bds == -1 && !(status & XAXIDMA_BD_STS_COMPLETE_MASK))
++ if (!force && !(status & XAXIDMA_BD_STS_COMPLETE_MASK))
+ break;
+
+ /* Ensure we see complete descriptor update */
+@@ -708,7 +703,7 @@ static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd,
+ DMA_TO_DEVICE);
+
+ if (cur_p->skb && (status & XAXIDMA_BD_STS_COMPLETE_MASK))
+- dev_consume_skb_irq(cur_p->skb);
++ napi_consume_skb(cur_p->skb, budget);
+
+ cur_p->app0 = 0;
+ cur_p->app1 = 0;
+@@ -738,14 +733,14 @@ static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd,
+ * This function is invoked before BDs are allocated and transmission starts.
+ * This function returns 0 if a BD or group of BDs can be allocated for
+ * transmission. If the BD or any of the BDs are not free the function
+- * returns a busy status. This is invoked from axienet_start_xmit.
++ * returns a busy status.
+ */
+ static inline int axienet_check_tx_bd_space(struct axienet_local *lp,
+ int num_frag)
+ {
+ struct axidma_bd *cur_p;
+
+- /* Ensure we see all descriptor updates from device or TX IRQ path */
++ /* Ensure we see all descriptor updates from device or TX polling */
+ rmb();
+ cur_p = &lp->tx_bd_v[(READ_ONCE(lp->tx_bd_tail) + num_frag) %
+ lp->tx_bd_num];
+@@ -755,36 +750,51 @@ static inline int axienet_check_tx_bd_space(struct axienet_local *lp,
+ }
+
+ /**
+- * axienet_start_xmit_done - Invoked once a transmit is completed by the
++ * axienet_tx_poll - Invoked once a transmit is completed by the
+ * Axi DMA Tx channel.
+- * @ndev: Pointer to the net_device structure
++ * @napi: Pointer to NAPI structure.
++ * @budget: Max number of TX packets to process.
++ *
++ * Return: Number of TX packets processed.
+ *
+- * This function is invoked from the Axi DMA Tx isr to notify the completion
++ * This function is invoked from the NAPI processing to notify the completion
+ * of transmit operation. It clears fields in the corresponding Tx BDs and
+ * unmaps the corresponding buffer so that CPU can regain ownership of the
+ * buffer. It finally invokes "netif_wake_queue" to restart transmission if
+ * required.
+ */
+-static void axienet_start_xmit_done(struct net_device *ndev)
++static int axienet_tx_poll(struct napi_struct *napi, int budget)
+ {
+- struct axienet_local *lp = netdev_priv(ndev);
+- u32 packets = 0;
++ struct axienet_local *lp = container_of(napi, struct axienet_local, napi_tx);
++ struct net_device *ndev = lp->ndev;
+ u32 size = 0;
++ int packets;
+
+- packets = axienet_free_tx_chain(ndev, lp->tx_bd_ci, -1, &size);
++ packets = axienet_free_tx_chain(lp, lp->tx_bd_ci, budget, false, &size, budget);
+
+- lp->tx_bd_ci += packets;
+- if (lp->tx_bd_ci >= lp->tx_bd_num)
+- lp->tx_bd_ci -= lp->tx_bd_num;
++ if (packets) {
++ lp->tx_bd_ci += packets;
++ if (lp->tx_bd_ci >= lp->tx_bd_num)
++ lp->tx_bd_ci %= lp->tx_bd_num;
+
+- ndev->stats.tx_packets += packets;
+- ndev->stats.tx_bytes += size;
++ ndev->stats.tx_packets += packets;
++ ndev->stats.tx_bytes += size;
+
+- /* Matches barrier in axienet_start_xmit */
+- smp_mb();
++ /* Matches barrier in axienet_start_xmit */
++ smp_mb();
+
+- if (!axienet_check_tx_bd_space(lp, MAX_SKB_FRAGS + 1))
+- netif_wake_queue(ndev);
++ if (!axienet_check_tx_bd_space(lp, MAX_SKB_FRAGS + 1))
++ netif_wake_queue(ndev);
++ }
++
++ if (packets < budget && napi_complete_done(napi, packets)) {
++ /* Re-enable TX completion interrupts. This should
++ * cause an immediate interrupt if any TX packets are
++ * already pending.
++ */
++ axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, lp->tx_dma_cr);
++ }
++ return packets;
+ }
+
+ /**
+@@ -869,8 +879,8 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ if (net_ratelimit())
+ netdev_err(ndev, "TX DMA mapping error\n");
+ ndev->stats.tx_dropped++;
+- axienet_free_tx_chain(ndev, orig_tail_ptr, ii + 1,
+- NULL);
++ axienet_free_tx_chain(lp, orig_tail_ptr, ii + 1,
++ true, NULL, 0);
+ return NETDEV_TX_OK;
+ }
+ desc_set_phys_addr(lp, phys, cur_p);
+@@ -892,7 +902,7 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ if (axienet_check_tx_bd_space(lp, MAX_SKB_FRAGS + 1)) {
+ netif_stop_queue(ndev);
+
+- /* Matches barrier in axienet_start_xmit_done */
++ /* Matches barrier in axienet_tx_poll */
+ smp_mb();
+
+ /* Space might have just been freed - check again */
+@@ -904,13 +914,13 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ }
+
+ /**
+- * axienet_poll - Triggered by RX ISR to complete the received BD processing.
++ * axienet_rx_poll - Triggered by RX ISR to complete the BD processing.
+ * @napi: Pointer to NAPI structure.
+- * @budget: Max number of packets to process.
++ * @budget: Max number of RX packets to process.
+ *
+ * Return: Number of RX packets processed.
+ */
+-static int axienet_poll(struct napi_struct *napi, int budget)
++static int axienet_rx_poll(struct napi_struct *napi, int budget)
+ {
+ u32 length;
+ u32 csumstatus;
+@@ -919,7 +929,7 @@ static int axienet_poll(struct napi_struct *napi, int budget)
+ dma_addr_t tail_p = 0;
+ struct axidma_bd *cur_p;
+ struct sk_buff *skb, *new_skb;
+- struct axienet_local *lp = container_of(napi, struct axienet_local, napi);
++ struct axienet_local *lp = container_of(napi, struct axienet_local, napi_rx);
+
+ cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
+
+@@ -1022,8 +1032,8 @@ static int axienet_poll(struct napi_struct *napi, int budget)
+ *
+ * Return: IRQ_HANDLED if device generated a TX interrupt, IRQ_NONE otherwise.
+ *
+- * This is the Axi DMA Tx done Isr. It invokes "axienet_start_xmit_done"
+- * to complete the BD processing.
++ * This is the Axi DMA Tx done Isr. It invokes NAPI polling to complete the
++ * TX BD processing.
+ */
+ static irqreturn_t axienet_tx_irq(int irq, void *_ndev)
+ {
+@@ -1045,7 +1055,15 @@ static irqreturn_t axienet_tx_irq(int irq, void *_ndev)
+ (lp->tx_bd_v[lp->tx_bd_ci]).phys);
+ schedule_work(&lp->dma_err_task);
+ } else {
+- axienet_start_xmit_done(lp->ndev);
++ /* Disable further TX completion interrupts and schedule
++ * NAPI to handle the completions.
++ */
++ u32 cr = lp->tx_dma_cr;
++
++ cr &= ~(XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_DELAY_MASK);
++ axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr);
++
++ napi_schedule(&lp->napi_tx);
+ }
+
+ return IRQ_HANDLED;
+@@ -1089,7 +1107,7 @@ static irqreturn_t axienet_rx_irq(int irq, void *_ndev)
+ cr &= ~(XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_DELAY_MASK);
+ axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr);
+
+- napi_schedule(&lp->napi);
++ napi_schedule(&lp->napi_rx);
+ }
+
+ return IRQ_HANDLED;
+@@ -1165,7 +1183,8 @@ static int axienet_open(struct net_device *ndev)
+ /* Enable worker thread for Axi DMA error handling */
+ INIT_WORK(&lp->dma_err_task, axienet_dma_err_handler);
+
+- napi_enable(&lp->napi);
++ napi_enable(&lp->napi_rx);
++ napi_enable(&lp->napi_tx);
+
+ /* Enable interrupts for Axi DMA Tx */
+ ret = request_irq(lp->tx_irq, axienet_tx_irq, IRQF_SHARED,
+@@ -1192,7 +1211,8 @@ static int axienet_open(struct net_device *ndev)
+ err_rx_irq:
+ free_irq(lp->tx_irq, ndev);
+ err_tx_irq:
+- napi_disable(&lp->napi);
++ napi_disable(&lp->napi_tx);
++ napi_disable(&lp->napi_rx);
+ phylink_stop(lp->phylink);
+ phylink_disconnect_phy(lp->phylink);
+ cancel_work_sync(&lp->dma_err_task);
+@@ -1216,7 +1236,8 @@ static int axienet_stop(struct net_device *ndev)
+
+ dev_dbg(&ndev->dev, "axienet_close()\n");
+
+- napi_disable(&lp->napi);
++ napi_disable(&lp->napi_tx);
++ napi_disable(&lp->napi_rx);
+
+ phylink_stop(lp->phylink);
+ phylink_disconnect_phy(lp->phylink);
+@@ -1794,7 +1815,8 @@ static void axienet_dma_err_handler(struct work_struct *work)
+ dma_err_task);
+ struct net_device *ndev = lp->ndev;
+
+- napi_disable(&lp->napi);
++ napi_disable(&lp->napi_tx);
++ napi_disable(&lp->napi_rx);
+
+ axienet_setoptions(ndev, lp->options &
+ ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN));
+@@ -1860,7 +1882,8 @@ static void axienet_dma_err_handler(struct work_struct *work)
+ axienet_set_mac_address(ndev, NULL);
+ axienet_set_multicast_list(ndev);
+ axienet_setoptions(ndev, lp->options);
+- napi_enable(&lp->napi);
++ napi_enable(&lp->napi_rx);
++ napi_enable(&lp->napi_tx);
+ }
+
+ /**
+@@ -1909,7 +1932,8 @@ static int axienet_probe(struct platform_device *pdev)
+ lp->rx_bd_num = RX_BD_NUM_DEFAULT;
+ lp->tx_bd_num = TX_BD_NUM_DEFAULT;
+
+- netif_napi_add(ndev, &lp->napi, axienet_poll, NAPI_POLL_WEIGHT);
++ netif_napi_add(ndev, &lp->napi_rx, axienet_rx_poll, NAPI_POLL_WEIGHT);
++ netif_napi_add(ndev, &lp->napi_tx, axienet_tx_poll, NAPI_POLL_WEIGHT);
+
+ lp->axi_clk = devm_clk_get_optional(&pdev->dev, "s_axi_lite_clk");
+ if (!lp->axi_clk) {
+--
+2.43.0
+
--- /dev/null
+From e78e602cfed5d556d7b25f68c0c47172ff4e42d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Sep 2024 17:44:44 +0800
+Subject: net: enetc: Use IRQF_NO_AUTOEN flag in request_irq()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 799a9225997799f7b1b579bc50a93b78b4fb2a01 ]
+
+disable_irq() after request_irq() still has a time gap in which
+interrupts can come. request_irq() with IRQF_NO_AUTOEN flag will
+disable IRQ auto-enable when request IRQ.
+
+Fixes: bbb96dc7fa1a ("enetc: Factor out the traffic start/stop procedures")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Link: https://patch.msgid.link/20240911094445.1922476-3-ruanjinjie@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/enetc/enetc.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
+index e16bd2b7692f3..9e063eb17f527 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -1883,12 +1883,11 @@ static int enetc_setup_irqs(struct enetc_ndev_priv *priv)
+
+ snprintf(v->name, sizeof(v->name), "%s-rxtx%d",
+ priv->ndev->name, i);
+- err = request_irq(irq, enetc_msix, 0, v->name, v);
++ err = request_irq(irq, enetc_msix, IRQF_NO_AUTOEN, v->name, v);
+ if (err) {
+ dev_err(priv->dev, "request_irq() failed!\n");
+ goto irq_err;
+ }
+- disable_irq(irq);
+
+ v->tbier_base = hw->reg + ENETC_BDR(TX, 0, ENETC_TBIER);
+ v->rbier = hw->reg + ENETC_BDR(RX, i, ENETC_RBIER);
+--
+2.43.0
+
--- /dev/null
+From 8f5431d99cfb333d0536ff79f9a77df44b2b378a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Mar 2022 08:15:57 +0200
+Subject: net: geneve: support IPv4/IPv6 as inner protocol
+
+From: Eyal Birger <eyal.birger@gmail.com>
+
+[ Upstream commit 435fe1c0c1f74b682dba85641406abf4337aade6 ]
+
+This patch adds support for encapsulating IPv4/IPv6 within GENEVE.
+
+In order to use this, a new IFLA_GENEVE_INNER_PROTO_INHERIT flag needs
+to be provided at device creation. This property cannot be changed for
+the time being.
+
+In case IP traffic is received on a non-tun device the drop count is
+increased.
+
+Signed-off-by: Eyal Birger <eyal.birger@gmail.com>
+Link: https://lore.kernel.org/r/20220316061557.431872-1-eyal.birger@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: c471236b2359 ("bareudp: Pull inner IP header on xmit.")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/geneve.c | 82 +++++++++++++++++++++++++++---------
+ include/uapi/linux/if_link.h | 1 +
+ 2 files changed, 64 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
+index 1bff01f8b16dc..6790fec36a6cb 100644
+--- a/drivers/net/geneve.c
++++ b/drivers/net/geneve.c
+@@ -55,6 +55,7 @@ struct geneve_config {
+ bool use_udp6_rx_checksums;
+ bool ttl_inherit;
+ enum ifla_geneve_df df;
++ bool inner_proto_inherit;
+ };
+
+ /* Pseudo network device */
+@@ -250,17 +251,24 @@ static void geneve_rx(struct geneve_dev *geneve, struct geneve_sock *gs,
+ }
+ }
+
+- skb_reset_mac_header(skb);
+- skb->protocol = eth_type_trans(skb, geneve->dev);
+- skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
+-
+ if (tun_dst)
+ skb_dst_set(skb, &tun_dst->dst);
+
+- /* Ignore packet loops (and multicast echo) */
+- if (ether_addr_equal(eth_hdr(skb)->h_source, geneve->dev->dev_addr)) {
+- geneve->dev->stats.rx_errors++;
+- goto drop;
++ if (gnvh->proto_type == htons(ETH_P_TEB)) {
++ skb_reset_mac_header(skb);
++ skb->protocol = eth_type_trans(skb, geneve->dev);
++ skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
++
++ /* Ignore packet loops (and multicast echo) */
++ if (ether_addr_equal(eth_hdr(skb)->h_source,
++ geneve->dev->dev_addr)) {
++ geneve->dev->stats.rx_errors++;
++ goto drop;
++ }
++ } else {
++ skb_reset_mac_header(skb);
++ skb->dev = geneve->dev;
++ skb->pkt_type = PACKET_HOST;
+ }
+
+ /* Save offset of outer header relative to skb->head,
+@@ -358,6 +366,7 @@ static int geneve_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
+ struct genevehdr *geneveh;
+ struct geneve_dev *geneve;
+ struct geneve_sock *gs;
++ __be16 inner_proto;
+ int opts_len;
+
+ /* Need UDP and Geneve header to be present */
+@@ -369,7 +378,11 @@ static int geneve_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
+ if (unlikely(geneveh->ver != GENEVE_VER))
+ goto drop;
+
+- if (unlikely(geneveh->proto_type != htons(ETH_P_TEB)))
++ inner_proto = geneveh->proto_type;
++
++ if (unlikely((inner_proto != htons(ETH_P_TEB) &&
++ inner_proto != htons(ETH_P_IP) &&
++ inner_proto != htons(ETH_P_IPV6))))
+ goto drop;
+
+ gs = rcu_dereference_sk_user_data(sk);
+@@ -380,9 +393,14 @@ static int geneve_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
+ if (!geneve)
+ goto drop;
+
++ if (unlikely((!geneve->cfg.inner_proto_inherit &&
++ inner_proto != htons(ETH_P_TEB)))) {
++ geneve->dev->stats.rx_dropped++;
++ goto drop;
++ }
++
+ opts_len = geneveh->opt_len * 4;
+- if (iptunnel_pull_header(skb, GENEVE_BASE_HLEN + opts_len,
+- htons(ETH_P_TEB),
++ if (iptunnel_pull_header(skb, GENEVE_BASE_HLEN + opts_len, inner_proto,
+ !net_eq(geneve->net, dev_net(geneve->dev)))) {
+ geneve->dev->stats.rx_dropped++;
+ goto drop;
+@@ -730,7 +748,8 @@ static int geneve_stop(struct net_device *dev)
+ }
+
+ static void geneve_build_header(struct genevehdr *geneveh,
+- const struct ip_tunnel_info *info)
++ const struct ip_tunnel_info *info,
++ __be16 inner_proto)
+ {
+ geneveh->ver = GENEVE_VER;
+ geneveh->opt_len = info->options_len / 4;
+@@ -738,7 +757,7 @@ static void geneve_build_header(struct genevehdr *geneveh,
+ geneveh->critical = !!(info->key.tun_flags & TUNNEL_CRIT_OPT);
+ geneveh->rsvd1 = 0;
+ tunnel_id_to_vni(info->key.tun_id, geneveh->vni);
+- geneveh->proto_type = htons(ETH_P_TEB);
++ geneveh->proto_type = inner_proto;
+ geneveh->rsvd2 = 0;
+
+ if (info->key.tun_flags & TUNNEL_GENEVE_OPT)
+@@ -747,10 +766,12 @@ static void geneve_build_header(struct genevehdr *geneveh,
+
+ static int geneve_build_skb(struct dst_entry *dst, struct sk_buff *skb,
+ const struct ip_tunnel_info *info,
+- bool xnet, int ip_hdr_len)
++ bool xnet, int ip_hdr_len,
++ bool inner_proto_inherit)
+ {
+ bool udp_sum = !!(info->key.tun_flags & TUNNEL_CSUM);
+ struct genevehdr *gnvh;
++ __be16 inner_proto;
+ int min_headroom;
+ int err;
+
+@@ -768,8 +789,9 @@ static int geneve_build_skb(struct dst_entry *dst, struct sk_buff *skb,
+ goto free_dst;
+
+ gnvh = __skb_push(skb, sizeof(*gnvh) + info->options_len);
+- geneve_build_header(gnvh, info);
+- skb_set_inner_protocol(skb, htons(ETH_P_TEB));
++ inner_proto = inner_proto_inherit ? skb->protocol : htons(ETH_P_TEB);
++ geneve_build_header(gnvh, info, inner_proto);
++ skb_set_inner_protocol(skb, inner_proto);
+ return 0;
+
+ free_dst:
+@@ -975,7 +997,8 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ }
+ }
+
+- err = geneve_build_skb(&rt->dst, skb, info, xnet, sizeof(struct iphdr));
++ err = geneve_build_skb(&rt->dst, skb, info, xnet, sizeof(struct iphdr),
++ geneve->cfg.inner_proto_inherit);
+ if (unlikely(err))
+ return err;
+
+@@ -1054,7 +1077,8 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ ttl = key->ttl;
+ ttl = ttl ? : ip6_dst_hoplimit(dst);
+ }
+- err = geneve_build_skb(dst, skb, info, xnet, sizeof(struct ipv6hdr));
++ err = geneve_build_skb(dst, skb, info, xnet, sizeof(struct ipv6hdr),
++ geneve->cfg.inner_proto_inherit);
+ if (unlikely(err))
+ return err;
+
+@@ -1404,6 +1428,14 @@ static int geneve_configure(struct net *net, struct net_device *dev,
+ dst_cache_reset(&geneve->cfg.info.dst_cache);
+ memcpy(&geneve->cfg, cfg, sizeof(*cfg));
+
++ if (geneve->cfg.inner_proto_inherit) {
++ dev->header_ops = NULL;
++ dev->type = ARPHRD_NONE;
++ dev->hard_header_len = 0;
++ dev->addr_len = 0;
++ dev->flags = IFF_NOARP;
++ }
++
+ err = register_netdevice(dev);
+ if (err)
+ return err;
+@@ -1577,10 +1609,18 @@ static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
+ #endif
+ }
+
++ if (data[IFLA_GENEVE_INNER_PROTO_INHERIT]) {
++ if (changelink) {
++ attrtype = IFLA_GENEVE_INNER_PROTO_INHERIT;
++ goto change_notsup;
++ }
++ cfg->inner_proto_inherit = true;
++ }
++
+ return 0;
+ change_notsup:
+ NL_SET_ERR_MSG_ATTR(extack, data[attrtype],
+- "Changing VNI, Port, endpoint IP address family, external, and UDP checksum attributes are not supported");
++ "Changing VNI, Port, endpoint IP address family, external, inner_proto_inherit, and UDP checksum attributes are not supported");
+ return -EOPNOTSUPP;
+ }
+
+@@ -1815,6 +1855,10 @@ static int geneve_fill_info(struct sk_buff *skb, const struct net_device *dev)
+ if (nla_put_u8(skb, IFLA_GENEVE_TTL_INHERIT, ttl_inherit))
+ goto nla_put_failure;
+
++ if (geneve->cfg.inner_proto_inherit &&
++ nla_put_flag(skb, IFLA_GENEVE_INNER_PROTO_INHERIT))
++ goto nla_put_failure;
++
+ return 0;
+
+ nla_put_failure:
+diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
+index 4ac53b30b6dc9..cc126982fa3c0 100644
+--- a/include/uapi/linux/if_link.h
++++ b/include/uapi/linux/if_link.h
+@@ -776,6 +776,7 @@ enum {
+ IFLA_GENEVE_LABEL,
+ IFLA_GENEVE_TTL_INHERIT,
+ IFLA_GENEVE_DF,
++ IFLA_GENEVE_INNER_PROTO_INHERIT,
+ __IFLA_GENEVE_MAX
+ };
+ #define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)
+--
+2.43.0
+
--- /dev/null
+From bd821da31535509ab42a1ba6f77d8fdf8242f8e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Sep 2024 19:45:57 +0200
+Subject: net: ipv6: rpl_iptunnel: Fix memory leak in rpl_input
+
+From: Justin Iurman <justin.iurman@uliege.be>
+
+[ Upstream commit 2c84b0aa28b9e73e8c4b4ce038269469434ae372 ]
+
+Free the skb before returning from rpl_input when skb_cow_head() fails.
+Use a "drop" label and goto instructions.
+
+Fixes: a7a29f9c361f ("net: ipv6: add rpl sr tunnel")
+Signed-off-by: Justin Iurman <justin.iurman@uliege.be>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20240911174557.11536-1-justin.iurman@uliege.be
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/rpl_iptunnel.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/net/ipv6/rpl_iptunnel.c b/net/ipv6/rpl_iptunnel.c
+index 26adbe7f8a2f0..c1d0f947a7c87 100644
+--- a/net/ipv6/rpl_iptunnel.c
++++ b/net/ipv6/rpl_iptunnel.c
+@@ -263,10 +263,8 @@ static int rpl_input(struct sk_buff *skb)
+ rlwt = rpl_lwt_lwtunnel(orig_dst->lwtstate);
+
+ err = rpl_do_srh(skb, rlwt);
+- if (unlikely(err)) {
+- kfree_skb(skb);
+- return err;
+- }
++ if (unlikely(err))
++ goto drop;
+
+ local_bh_disable();
+ dst = dst_cache_get(&rlwt->cache);
+@@ -287,9 +285,13 @@ static int rpl_input(struct sk_buff *skb)
+
+ err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev));
+ if (unlikely(err))
+- return err;
++ goto drop;
+
+ return dst_input(skb);
++
++drop:
++ kfree_skb(skb);
++ return err;
+ }
+
+ static int nla_put_rpl_srh(struct sk_buff *skb, int attrtype,
+--
+2.43.0
+
--- /dev/null
+From 2398ab2685587fac0523f4eb36c4f394dd8f0620 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Sep 2024 20:57:13 +0200
+Subject: net: ipv6: select DST_CACHE from IPV6_RPL_LWTUNNEL
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
+
+[ Upstream commit 93c21077bb9ba08807c459982d440dbbee4c7af3 ]
+
+The rpl sr tunnel code contains calls to dst_cache_*() which are
+only present when the dst cache is built.
+Select DST_CACHE to build the dst cache, similar to other kconfig
+options in the same file.
+Compiling the rpl sr tunnel without DST_CACHE will lead to linker
+errors.
+
+Fixes: a7a29f9c361f ("net: ipv6: add rpl sr tunnel")
+Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Simon Horman <horms@kernel.org> # build-tested
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
+index e504204bca924..a7e79851256b7 100644
+--- a/net/ipv6/Kconfig
++++ b/net/ipv6/Kconfig
+@@ -322,6 +322,7 @@ config IPV6_RPL_LWTUNNEL
+ bool "IPv6: RPL Source Routing Header support"
+ depends on IPV6
+ select LWTUNNEL
++ select DST_CACHE
+ help
+ Support for RFC6554 RPL Source Routing Header using the lightweight
+ tunnels mechanism.
+--
+2.43.0
+
--- /dev/null
+From 3ea0a8d1a1ee0c60d8fb9af2bc7c398bf698df33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Sep 2024 19:08:58 +0200
+Subject: net: qrtr: Update packets cloning when broadcasting
+
+From: Youssef Samir <quic_yabdulra@quicinc.com>
+
+[ Upstream commit f011b313e8ebd5b7abd8521b5119aecef403de45 ]
+
+When broadcasting data to multiple nodes via MHI, using skb_clone()
+causes all nodes to receive the same header data. This can result in
+packets being discarded by endpoints, leading to lost data.
+
+This issue occurs when a socket is closed, and a QRTR_TYPE_DEL_CLIENT
+packet is broadcasted. All nodes receive the same destination node ID,
+causing the node connected to the client to discard the packet and
+remain unaware of the client's deletion.
+
+Replace skb_clone() with pskb_copy(), to create a separate copy of
+the header for each sk_buff.
+
+Fixes: bdabad3e363d ("net: Add Qualcomm IPC router")
+Signed-off-by: Youssef Samir <quic_yabdulra@quicinc.com>
+Reviewed-by: Jeffery Hugo <quic_jhugo@quicinc.com>
+Reviewed-by: Carl Vanderlip <quic_carlv@quicinc.com>
+Reviewed-by: Chris Lew <quic_clew@quicinc.com>
+Link: https://patch.msgid.link/20240916170858.2382247-1-quic_yabdulra@quicinc.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/qrtr/af_qrtr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/qrtr/af_qrtr.c b/net/qrtr/af_qrtr.c
+index e0a27a404404f..c7a8260fa6ddb 100644
+--- a/net/qrtr/af_qrtr.c
++++ b/net/qrtr/af_qrtr.c
+@@ -879,7 +879,7 @@ static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb,
+
+ mutex_lock(&qrtr_node_lock);
+ list_for_each_entry(node, &qrtr_all_nodes, item) {
+- skbn = skb_clone(skb, GFP_KERNEL);
++ skbn = pskb_copy(skb, GFP_KERNEL);
+ if (!skbn)
+ break;
+ skb_set_owner_w(skbn, skb->sk);
+--
+2.43.0
+
--- /dev/null
+From b0a047c77731d1e2e131eb6f7252410178705fdf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 Sep 2024 22:40:46 +0800
+Subject: net: seeq: Fix use after free vulnerability in ether3 Driver Due to
+ Race Condition
+
+From: Kaixin Wang <kxwang23@m.fudan.edu.cn>
+
+[ Upstream commit b5109b60ee4fcb2f2bb24f589575e10cc5283ad4 ]
+
+In the ether3_probe function, a timer is initialized with a callback
+function ether3_ledoff, bound to &prev(dev)->timer. Once the timer is
+started, there is a risk of a race condition if the module or device
+is removed, triggering the ether3_remove function to perform cleanup.
+The sequence of operations that may lead to a UAF bug is as follows:
+
+CPU0 CPU1
+
+ | ether3_ledoff
+ether3_remove |
+ free_netdev(dev); |
+ put_devic |
+ kfree(dev); |
+ | ether3_outw(priv(dev)->regs.config2 |= CFG2_CTRLO, REG_CONFIG2);
+ | // use dev
+
+Fix it by ensuring that the timer is canceled before proceeding with
+the cleanup in ether3_remove.
+
+Fixes: 6fd9c53f7186 ("net: seeq: Convert timers to use timer_setup()")
+Signed-off-by: Kaixin Wang <kxwang23@m.fudan.edu.cn>
+Link: https://patch.msgid.link/20240915144045.451-1-kxwang23@m.fudan.edu.cn
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/seeq/ether3.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/seeq/ether3.c b/drivers/net/ethernet/seeq/ether3.c
+index 16a4cbae93265..6bcb52118c11b 100644
+--- a/drivers/net/ethernet/seeq/ether3.c
++++ b/drivers/net/ethernet/seeq/ether3.c
+@@ -845,9 +845,11 @@ static void ether3_remove(struct expansion_card *ec)
+ {
+ struct net_device *dev = ecard_get_drvdata(ec);
+
++ ether3_outw(priv(dev)->regs.config2 |= CFG2_CTRLO, REG_CONFIG2);
+ ecard_set_drvdata(ec, NULL);
+
+ unregister_netdev(dev);
++ del_timer_sync(&priv(dev)->timer);
+ free_netdev(dev);
+ ecard_release_resources(ec);
+ }
+--
+2.43.0
+
--- /dev/null
+From f0512a9849290a3ec6848d59c1db3daec51fa3c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Aug 2024 21:48:02 +0800
+Subject: net: stmmac: dwmac-loongson: Init ref and PTP clocks rate
+
+From: Yanteng Si <siyanteng@loongson.cn>
+
+[ Upstream commit c70f3163681381c15686bdd2fe56bf4af9b8aaaa ]
+
+Reference and PTP clocks rate of the Loongson GMAC devices is 125MHz.
+(So is in the GNET devices which support is about to be added.) Set
+the respective plat_stmmacenet_data field up in accordance with that
+so to have the coalesce command and timestamping work correctly.
+
+Fixes: 30bba69d7db4 ("stmmac: pci: Add dwmac support for Loongson")
+Signed-off-by: Feiyang Chen <chenfeiyang@loongson.cn>
+Signed-off-by: Yinggang Gu <guyinggang@loongson.cn>
+Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
+Acked-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Yanteng Si <siyanteng@loongson.cn>
+Tested-by: Serge Semin <fancer.lancer@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+index da7b5d26a5897..da2e68d616225 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+@@ -35,6 +35,9 @@ static int loongson_default_data(struct plat_stmmacenet_data *plat)
+ /* Disable RX queues routing by default */
+ plat->rx_queues_cfg[0].pkt_route = 0x0;
+
++ plat->clk_ref_rate = 125000000;
++ plat->clk_ptp_rate = 125000000;
++
+ /* Default to phy auto-detection */
+ plat->phy_addr = -1;
+
+--
+2.43.0
+
--- /dev/null
+From 672c49f7aff76fa9e0abbcd6bf609a0a8a68f726 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Sep 2024 19:01:20 +0800
+Subject: net: tipc: avoid possible garbage value
+
+From: Su Hui <suhui@nfschina.com>
+
+[ Upstream commit 99655a304e450baaae6b396cb942b9e47659d644 ]
+
+Clang static checker (scan-build) warning:
+net/tipc/bcast.c:305:4:
+The expression is an uninitialized value. The computed value will also
+be garbage [core.uninitialized.Assign]
+ 305 | (*cong_link_cnt)++;
+ | ^~~~~~~~~~~~~~~~~~
+
+tipc_rcast_xmit() will increase cong_link_cnt's value, but cong_link_cnt
+is uninitialized. Although it won't really cause a problem, it's better
+to fix it.
+
+Fixes: dca4a17d24ee ("tipc: fix potential hanging after b/rcast changing")
+Signed-off-by: Su Hui <suhui@nfschina.com>
+Reviewed-by: Justin Stitt <justinstitt@google.com>
+Link: https://patch.msgid.link/20240912110119.2025503-1-suhui@nfschina.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/bcast.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
+index 593846d252143..114fef65f92ea 100644
+--- a/net/tipc/bcast.c
++++ b/net/tipc/bcast.c
+@@ -320,8 +320,8 @@ static int tipc_mcast_send_sync(struct net *net, struct sk_buff *skb,
+ {
+ struct tipc_msg *hdr, *_hdr;
+ struct sk_buff_head tmpq;
++ u16 cong_link_cnt = 0;
+ struct sk_buff *_skb;
+- u16 cong_link_cnt;
+ int rc = 0;
+
+ /* Is a cluster supporting with new capabilities ? */
+--
+2.43.0
+
--- /dev/null
+From 6b1b471933543d8c9ecc882c38f8a50044d33a3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Sep 2024 10:51:56 -0400
+Subject: net: xilinx: axienet: Fix packet counting
+
+From: Sean Anderson <sean.anderson@linux.dev>
+
+[ Upstream commit 5a6caa2cfabb559309b5ce29ee7c8e9ce1a9a9df ]
+
+axienet_free_tx_chain returns the number of DMA descriptors it's
+handled. However, axienet_tx_poll treats the return as the number of
+packets. When scatter-gather SKBs are enabled, a single packet may use
+multiple DMA descriptors, which causes incorrect packet counts. Fix this
+by explicitly keepting track of the number of packets processed as
+separate from the DMA descriptors.
+
+Budget does not affect the number of Tx completions we can process for
+NAPI, so we use the ring size as the limit instead of budget. As we no
+longer return the number of descriptors processed to axienet_tx_poll, we
+now update tx_bd_ci in axienet_free_tx_chain.
+
+Fixes: 8a3b7a252dca ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Link: https://patch.msgid.link/20240913145156.2283067-1-sean.anderson@linux.dev
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/xilinx/xilinx_axienet_main.c | 23 +++++++++++--------
+ 1 file changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+index 9805b81bd490a..29863922253f2 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -675,15 +675,15 @@ static int axienet_device_reset(struct net_device *ndev)
+ *
+ * Would either be called after a successful transmit operation, or after
+ * there was an error when setting up the chain.
+- * Returns the number of descriptors handled.
++ * Returns the number of packets handled.
+ */
+ static int axienet_free_tx_chain(struct axienet_local *lp, u32 first_bd,
+ int nr_bds, bool force, u32 *sizep, int budget)
+ {
+ struct axidma_bd *cur_p;
+ unsigned int status;
++ int i, packets = 0;
+ dma_addr_t phys;
+- int i;
+
+ for (i = 0; i < nr_bds; i++) {
+ cur_p = &lp->tx_bd_v[(first_bd + i) % lp->tx_bd_num];
+@@ -702,8 +702,10 @@ static int axienet_free_tx_chain(struct axienet_local *lp, u32 first_bd,
+ (cur_p->cntrl & XAXIDMA_BD_CTRL_LENGTH_MASK),
+ DMA_TO_DEVICE);
+
+- if (cur_p->skb && (status & XAXIDMA_BD_STS_COMPLETE_MASK))
++ if (cur_p->skb && (status & XAXIDMA_BD_STS_COMPLETE_MASK)) {
+ napi_consume_skb(cur_p->skb, budget);
++ packets++;
++ }
+
+ cur_p->app0 = 0;
+ cur_p->app1 = 0;
+@@ -719,7 +721,13 @@ static int axienet_free_tx_chain(struct axienet_local *lp, u32 first_bd,
+ *sizep += status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK;
+ }
+
+- return i;
++ if (!force) {
++ lp->tx_bd_ci += i;
++ if (lp->tx_bd_ci >= lp->tx_bd_num)
++ lp->tx_bd_ci %= lp->tx_bd_num;
++ }
++
++ return packets;
+ }
+
+ /**
+@@ -770,13 +778,10 @@ static int axienet_tx_poll(struct napi_struct *napi, int budget)
+ u32 size = 0;
+ int packets;
+
+- packets = axienet_free_tx_chain(lp, lp->tx_bd_ci, budget, false, &size, budget);
++ packets = axienet_free_tx_chain(lp, lp->tx_bd_ci, lp->tx_bd_num, false,
++ &size, budget);
+
+ if (packets) {
+- lp->tx_bd_ci += packets;
+- if (lp->tx_bd_ci >= lp->tx_bd_num)
+- lp->tx_bd_ci %= lp->tx_bd_num;
+-
+ u64_stats_update_begin(&lp->tx_stat_sync);
+ u64_stats_add(&lp->tx_packets, packets);
+ u64_stats_add(&lp->tx_bytes, size);
+--
+2.43.0
+
--- /dev/null
+From 85edb39b94a9e6a6573cf61a88c4e6f09d18cce8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Sep 2024 16:14:41 +0100
+Subject: netfilter: ctnetlink: compile ctnetlink_label_size with
+ CONFIG_NF_CONNTRACK_EVENTS
+
+From: Simon Horman <horms@kernel.org>
+
+[ Upstream commit e1f1ee0e9ad8cbe660f5c104e791c5f1a7cf4c31 ]
+
+Only provide ctnetlink_label_size when it is used,
+which is when CONFIG_NF_CONNTRACK_EVENTS is configured.
+
+Flagged by clang-18 W=1 builds as:
+
+.../nf_conntrack_netlink.c:385:19: warning: unused function 'ctnetlink_label_size' [-Wunused-function]
+ 385 | static inline int ctnetlink_label_size(const struct nf_conn *ct)
+ | ^~~~~~~~~~~~~~~~~~~~
+
+The condition on CONFIG_NF_CONNTRACK_LABELS being removed by
+this patch guards compilation of non-trivial implementations
+of ctnetlink_dump_labels() and ctnetlink_label_size().
+
+However, this is not necessary as each of these functions
+will always return 0 if CONFIG_NF_CONNTRACK_LABELS is not defined
+as each function starts with the equivalent of:
+
+ struct nf_conn_labels *labels = nf_ct_labels_find(ct);
+
+ if (!labels)
+ return 0;
+
+And nf_ct_labels_find always returns NULL if CONFIG_NF_CONNTRACK_LABELS
+is not enabled. So I believe that the compiler optimises the code away
+in such cases anyway.
+
+Found by inspection.
+Compile tested only.
+
+Originally splitted in two patches, Pablo Neira Ayuso collapsed them and
+added Fixes: tag.
+
+Fixes: 0ceabd83875b ("netfilter: ctnetlink: deliver labels to userspace")
+Link: https://lore.kernel.org/netfilter-devel/20240909151712.GZ2097826@kernel.org/
+Signed-off-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conntrack_netlink.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
+index b429ffde25b1a..585103c16a8af 100644
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -370,7 +370,7 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct)
+ #define ctnetlink_dump_secctx(a, b) (0)
+ #endif
+
+-#ifdef CONFIG_NF_CONNTRACK_LABELS
++#ifdef CONFIG_NF_CONNTRACK_EVENTS
+ static inline int ctnetlink_label_size(const struct nf_conn *ct)
+ {
+ struct nf_conn_labels *labels = nf_ct_labels_find(ct);
+@@ -379,6 +379,7 @@ static inline int ctnetlink_label_size(const struct nf_conn *ct)
+ return 0;
+ return nla_total_size(sizeof(labels->bits));
+ }
++#endif
+
+ static int
+ ctnetlink_dump_labels(struct sk_buff *skb, const struct nf_conn *ct)
+@@ -399,10 +400,6 @@ ctnetlink_dump_labels(struct sk_buff *skb, const struct nf_conn *ct)
+
+ return 0;
+ }
+-#else
+-#define ctnetlink_dump_labels(a, b) (0)
+-#define ctnetlink_label_size(a) (0)
+-#endif
+
+ #define master_tuple(ct) &(ct->master->tuplehash[IP_CT_DIR_ORIGINAL].tuple)
+
+--
+2.43.0
+
--- /dev/null
+From d69ffa54343dd1a834d1f92d2b537d59597995cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Sep 2024 17:06:15 +0000
+Subject: netfilter: nf_reject_ipv6: fix nf_reject_ip6_tcphdr_put()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 9c778fe48d20ef362047e3376dee56d77f8500d4 ]
+
+syzbot reported that nf_reject_ip6_tcphdr_put() was possibly sending
+garbage on the four reserved tcp bits (th->res1)
+
+Use skb_put_zero() to clear the whole TCP header,
+as done in nf_reject_ip_tcphdr_put()
+
+BUG: KMSAN: uninit-value in nf_reject_ip6_tcphdr_put+0x688/0x6c0 net/ipv6/netfilter/nf_reject_ipv6.c:255
+ nf_reject_ip6_tcphdr_put+0x688/0x6c0 net/ipv6/netfilter/nf_reject_ipv6.c:255
+ nf_send_reset6+0xd84/0x15b0 net/ipv6/netfilter/nf_reject_ipv6.c:344
+ nft_reject_inet_eval+0x3c1/0x880 net/netfilter/nft_reject_inet.c:48
+ expr_call_ops_eval net/netfilter/nf_tables_core.c:240 [inline]
+ nft_do_chain+0x438/0x22a0 net/netfilter/nf_tables_core.c:288
+ nft_do_chain_inet+0x41a/0x4f0 net/netfilter/nft_chain_filter.c:161
+ nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline]
+ nf_hook_slow+0xf4/0x400 net/netfilter/core.c:626
+ nf_hook include/linux/netfilter.h:269 [inline]
+ NF_HOOK include/linux/netfilter.h:312 [inline]
+ ipv6_rcv+0x29b/0x390 net/ipv6/ip6_input.c:310
+ __netif_receive_skb_one_core net/core/dev.c:5661 [inline]
+ __netif_receive_skb+0x1da/0xa00 net/core/dev.c:5775
+ process_backlog+0x4ad/0xa50 net/core/dev.c:6108
+ __napi_poll+0xe7/0x980 net/core/dev.c:6772
+ napi_poll net/core/dev.c:6841 [inline]
+ net_rx_action+0xa5a/0x19b0 net/core/dev.c:6963
+ handle_softirqs+0x1ce/0x800 kernel/softirq.c:554
+ __do_softirq+0x14/0x1a kernel/softirq.c:588
+ do_softirq+0x9a/0x100 kernel/softirq.c:455
+ __local_bh_enable_ip+0x9f/0xb0 kernel/softirq.c:382
+ local_bh_enable include/linux/bottom_half.h:33 [inline]
+ rcu_read_unlock_bh include/linux/rcupdate.h:908 [inline]
+ __dev_queue_xmit+0x2692/0x5610 net/core/dev.c:4450
+ dev_queue_xmit include/linux/netdevice.h:3105 [inline]
+ neigh_resolve_output+0x9ca/0xae0 net/core/neighbour.c:1565
+ neigh_output include/net/neighbour.h:542 [inline]
+ ip6_finish_output2+0x2347/0x2ba0 net/ipv6/ip6_output.c:141
+ __ip6_finish_output net/ipv6/ip6_output.c:215 [inline]
+ ip6_finish_output+0xbb8/0x14b0 net/ipv6/ip6_output.c:226
+ NF_HOOK_COND include/linux/netfilter.h:303 [inline]
+ ip6_output+0x356/0x620 net/ipv6/ip6_output.c:247
+ dst_output include/net/dst.h:450 [inline]
+ NF_HOOK include/linux/netfilter.h:314 [inline]
+ ip6_xmit+0x1ba6/0x25d0 net/ipv6/ip6_output.c:366
+ inet6_csk_xmit+0x442/0x530 net/ipv6/inet6_connection_sock.c:135
+ __tcp_transmit_skb+0x3b07/0x4880 net/ipv4/tcp_output.c:1466
+ tcp_transmit_skb net/ipv4/tcp_output.c:1484 [inline]
+ tcp_connect+0x35b6/0x7130 net/ipv4/tcp_output.c:4143
+ tcp_v6_connect+0x1bcc/0x1e40 net/ipv6/tcp_ipv6.c:333
+ __inet_stream_connect+0x2ef/0x1730 net/ipv4/af_inet.c:679
+ inet_stream_connect+0x6a/0xd0 net/ipv4/af_inet.c:750
+ __sys_connect_file net/socket.c:2061 [inline]
+ __sys_connect+0x606/0x690 net/socket.c:2078
+ __do_sys_connect net/socket.c:2088 [inline]
+ __se_sys_connect net/socket.c:2085 [inline]
+ __x64_sys_connect+0x91/0xe0 net/socket.c:2085
+ x64_sys_call+0x27a5/0x3ba0 arch/x86/include/generated/asm/syscalls_64.h:43
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Uninit was stored to memory at:
+ nf_reject_ip6_tcphdr_put+0x60c/0x6c0 net/ipv6/netfilter/nf_reject_ipv6.c:249
+ nf_send_reset6+0xd84/0x15b0 net/ipv6/netfilter/nf_reject_ipv6.c:344
+ nft_reject_inet_eval+0x3c1/0x880 net/netfilter/nft_reject_inet.c:48
+ expr_call_ops_eval net/netfilter/nf_tables_core.c:240 [inline]
+ nft_do_chain+0x438/0x22a0 net/netfilter/nf_tables_core.c:288
+ nft_do_chain_inet+0x41a/0x4f0 net/netfilter/nft_chain_filter.c:161
+ nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline]
+ nf_hook_slow+0xf4/0x400 net/netfilter/core.c:626
+ nf_hook include/linux/netfilter.h:269 [inline]
+ NF_HOOK include/linux/netfilter.h:312 [inline]
+ ipv6_rcv+0x29b/0x390 net/ipv6/ip6_input.c:310
+ __netif_receive_skb_one_core net/core/dev.c:5661 [inline]
+ __netif_receive_skb+0x1da/0xa00 net/core/dev.c:5775
+ process_backlog+0x4ad/0xa50 net/core/dev.c:6108
+ __napi_poll+0xe7/0x980 net/core/dev.c:6772
+ napi_poll net/core/dev.c:6841 [inline]
+ net_rx_action+0xa5a/0x19b0 net/core/dev.c:6963
+ handle_softirqs+0x1ce/0x800 kernel/softirq.c:554
+ __do_softirq+0x14/0x1a kernel/softirq.c:588
+
+Uninit was stored to memory at:
+ nf_reject_ip6_tcphdr_put+0x2ca/0x6c0 net/ipv6/netfilter/nf_reject_ipv6.c:231
+ nf_send_reset6+0xd84/0x15b0 net/ipv6/netfilter/nf_reject_ipv6.c:344
+ nft_reject_inet_eval+0x3c1/0x880 net/netfilter/nft_reject_inet.c:48
+ expr_call_ops_eval net/netfilter/nf_tables_core.c:240 [inline]
+ nft_do_chain+0x438/0x22a0 net/netfilter/nf_tables_core.c:288
+ nft_do_chain_inet+0x41a/0x4f0 net/netfilter/nft_chain_filter.c:161
+ nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline]
+ nf_hook_slow+0xf4/0x400 net/netfilter/core.c:626
+ nf_hook include/linux/netfilter.h:269 [inline]
+ NF_HOOK include/linux/netfilter.h:312 [inline]
+ ipv6_rcv+0x29b/0x390 net/ipv6/ip6_input.c:310
+ __netif_receive_skb_one_core net/core/dev.c:5661 [inline]
+ __netif_receive_skb+0x1da/0xa00 net/core/dev.c:5775
+ process_backlog+0x4ad/0xa50 net/core/dev.c:6108
+ __napi_poll+0xe7/0x980 net/core/dev.c:6772
+ napi_poll net/core/dev.c:6841 [inline]
+ net_rx_action+0xa5a/0x19b0 net/core/dev.c:6963
+ handle_softirqs+0x1ce/0x800 kernel/softirq.c:554
+ __do_softirq+0x14/0x1a kernel/softirq.c:588
+
+Uninit was created at:
+ slab_post_alloc_hook mm/slub.c:3998 [inline]
+ slab_alloc_node mm/slub.c:4041 [inline]
+ kmem_cache_alloc_node_noprof+0x6bf/0xb80 mm/slub.c:4084
+ kmalloc_reserve+0x13d/0x4a0 net/core/skbuff.c:583
+ __alloc_skb+0x363/0x7b0 net/core/skbuff.c:674
+ alloc_skb include/linux/skbuff.h:1320 [inline]
+ nf_send_reset6+0x98d/0x15b0 net/ipv6/netfilter/nf_reject_ipv6.c:327
+ nft_reject_inet_eval+0x3c1/0x880 net/netfilter/nft_reject_inet.c:48
+ expr_call_ops_eval net/netfilter/nf_tables_core.c:240 [inline]
+ nft_do_chain+0x438/0x22a0 net/netfilter/nf_tables_core.c:288
+ nft_do_chain_inet+0x41a/0x4f0 net/netfilter/nft_chain_filter.c:161
+ nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline]
+ nf_hook_slow+0xf4/0x400 net/netfilter/core.c:626
+ nf_hook include/linux/netfilter.h:269 [inline]
+ NF_HOOK include/linux/netfilter.h:312 [inline]
+ ipv6_rcv+0x29b/0x390 net/ipv6/ip6_input.c:310
+ __netif_receive_skb_one_core net/core/dev.c:5661 [inline]
+ __netif_receive_skb+0x1da/0xa00 net/core/dev.c:5775
+ process_backlog+0x4ad/0xa50 net/core/dev.c:6108
+ __napi_poll+0xe7/0x980 net/core/dev.c:6772
+ napi_poll net/core/dev.c:6841 [inline]
+ net_rx_action+0xa5a/0x19b0 net/core/dev.c:6963
+ handle_softirqs+0x1ce/0x800 kernel/softirq.c:554
+ __do_softirq+0x14/0x1a kernel/softirq.c:588
+
+Fixes: c8d7b98bec43 ("netfilter: move nf_send_resetX() code to nf_reject_ipvX modules")
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Link: https://patch.msgid.link/20240913170615.3670897-1-edumazet@google.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/netfilter/nf_reject_ipv6.c | 14 ++------------
+ 1 file changed, 2 insertions(+), 12 deletions(-)
+
+diff --git a/net/ipv6/netfilter/nf_reject_ipv6.c b/net/ipv6/netfilter/nf_reject_ipv6.c
+index c0057edd84cfc..8208490e05a38 100644
+--- a/net/ipv6/netfilter/nf_reject_ipv6.c
++++ b/net/ipv6/netfilter/nf_reject_ipv6.c
+@@ -223,33 +223,23 @@ void nf_reject_ip6_tcphdr_put(struct sk_buff *nskb,
+ const struct tcphdr *oth, unsigned int otcplen)
+ {
+ struct tcphdr *tcph;
+- int needs_ack;
+
+ skb_reset_transport_header(nskb);
+- tcph = skb_put(nskb, sizeof(struct tcphdr));
++ tcph = skb_put_zero(nskb, sizeof(struct tcphdr));
+ /* Truncate to length (no data) */
+ tcph->doff = sizeof(struct tcphdr)/4;
+ tcph->source = oth->dest;
+ tcph->dest = oth->source;
+
+ if (oth->ack) {
+- needs_ack = 0;
+ tcph->seq = oth->ack_seq;
+- tcph->ack_seq = 0;
+ } else {
+- needs_ack = 1;
+ tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin +
+ otcplen - (oth->doff<<2));
+- tcph->seq = 0;
++ tcph->ack = 1;
+ }
+
+- /* Reset flags */
+- ((u_int8_t *)tcph)[13] = 0;
+ tcph->rst = 1;
+- tcph->ack = needs_ack;
+- tcph->window = 0;
+- tcph->urg_ptr = 0;
+- tcph->check = 0;
+
+ /* Adjust TCP checksum */
+ tcph->check = csum_ipv6_magic(&ipv6_hdr(nskb)->saddr,
+--
+2.43.0
+
--- /dev/null
+From af08227d656a5d41adaefa0b764b04c441231729 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Sep 2024 01:06:41 +0200
+Subject: netfilter: nf_tables: elements with timeout below CONFIG_HZ never
+ expire
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit e0c47281723f301894c14e6f5cd5884fdfb813f9 ]
+
+Element timeout that is below CONFIG_HZ never expires because the
+timeout extension is not allocated given that nf_msecs_to_jiffies64()
+returns 0. Set timeout to the minimum value to honor timeout.
+
+Fixes: 8e1102d5a159 ("netfilter: nf_tables: support timeouts larger than 23 days")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index df10a2047bb0e..c00a9495f3453 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -4153,7 +4153,7 @@ int nf_msecs_to_jiffies64(const struct nlattr *nla, u64 *result)
+ return -ERANGE;
+
+ ms *= NSEC_PER_MSEC;
+- *result = nsecs_to_jiffies64(ms);
++ *result = nsecs_to_jiffies64(ms) ? : !!ms;
+ return 0;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From aac93a2e12724aad10b346292d81e25ca4edcd20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Sep 2024 14:21:33 +0200
+Subject: netfilter: nf_tables: Keep deleted flowtable hooks until after RCU
+
+From: Phil Sutter <phil@nwl.cc>
+
+[ Upstream commit 642c89c475419b4d0c0d90e29d9c1a0e4351f379 ]
+
+Documentation of list_del_rcu() warns callers to not immediately free
+the deleted list item. While it seems not necessary to use the
+RCU-variant of list_del() here in the first place, doing so seems to
+require calling kfree_rcu() on the deleted item as well.
+
+Fixes: 3f0465a9ef02 ("netfilter: nf_tables: dynamically allocate hooks per net_device in flowtables")
+Signed-off-by: Phil Sutter <phil@nwl.cc>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index f493f4351ca52..71a486d9fd76a 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -8434,7 +8434,7 @@ static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable)
+ flowtable->data.type->setup(&flowtable->data, hook->ops.dev,
+ FLOW_BLOCK_UNBIND);
+ list_del_rcu(&hook->list);
+- kfree(hook);
++ kfree_rcu(hook, rcu);
+ }
+ kfree(flowtable->name);
+ module_put(flowtable->data.type->owner);
+--
+2.43.0
+
--- /dev/null
+From a687b177829cf5a39e83ba823e51a3d20293d1a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Sep 2024 01:06:49 +0200
+Subject: netfilter: nf_tables: reject element expiration with no timeout
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit d2dc429ecb4e79ad164028d965c00f689e6f6d06 ]
+
+If element timeout is unset and set provides no default timeout, the
+element expiration is silently ignored, reject this instead to let user
+know this is unsupported.
+
+Also prepare for supporting timeout that never expire, where zero
+timeout and expiration must be also rejected.
+
+Fixes: 8e1102d5a159 ("netfilter: nf_tables: support timeouts larger than 23 days")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index c00a9495f3453..300926b56572d 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -6295,6 +6295,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+ if (nla[NFTA_SET_ELEM_EXPIRATION] != NULL) {
+ if (!(set->flags & NFT_SET_TIMEOUT))
+ return -EINVAL;
++ if (timeout == 0)
++ return -EOPNOTSUPP;
++
+ err = nf_msecs_to_jiffies64(nla[NFTA_SET_ELEM_EXPIRATION],
+ &expiration);
+ if (err)
+--
+2.43.0
+
--- /dev/null
+From d66054942f3628a2dd5a96108677ab743b9f3104 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Sep 2024 01:06:58 +0200
+Subject: netfilter: nf_tables: reject expiration higher than timeout
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit c0f38a8c60174368aed1d0f9965d733195f15033 ]
+
+Report ERANGE to userspace if user specifies an expiration larger than
+the timeout.
+
+Fixes: 8e1102d5a159 ("netfilter: nf_tables: support timeouts larger than 23 days")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 300926b56572d..dff7e507d03a5 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -6302,6 +6302,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+ &expiration);
+ if (err)
+ return err;
++
++ if (expiration > timeout)
++ return -ERANGE;
+ }
+
+ if (nla[NFTA_SET_ELEM_EXPR]) {
+--
+2.43.0
+
--- /dev/null
+From 673c0290b31fed251da8b3b7ef1290fadcef0dbb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Sep 2024 01:07:06 +0200
+Subject: netfilter: nf_tables: remove annotation to access set timeout while
+ holding lock
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 15d8605c0cf4fc9cf4386cae658c68a0fd4bdb92 ]
+
+Mutex is held when adding an element, no need for READ_ONCE, remove it.
+
+Fixes: 123b99619cca ("netfilter: nf_tables: honor set timeout and garbage collection updates")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index dff7e507d03a5..f493f4351ca52 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -6288,7 +6288,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+ return err;
+ } else if (set->flags & NFT_SET_TIMEOUT &&
+ !(flags & NFT_SET_ELEM_INTERVAL_END)) {
+- timeout = READ_ONCE(set->timeout);
++ timeout = set->timeout;
+ }
+
+ expiration = 0;
+@@ -6395,7 +6395,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+ if (err < 0)
+ goto err_parse_key_end;
+
+- if (timeout != READ_ONCE(set->timeout)) {
++ if (timeout != set->timeout) {
+ err = nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
+ if (err < 0)
+ goto err_parse_key_end;
+--
+2.43.0
+
--- /dev/null
+From 667cf2f7bf98d4161bdc4cf9087cc79226f8e3e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Aug 2024 22:03:18 +0800
+Subject: nfsd: call cache_put if xdr_reserve_space returns NULL
+
+From: Guoqing Jiang <guoqing.jiang@linux.dev>
+
+[ Upstream commit d078cbf5c38de83bc31f83c47dcd2184c04a50c7 ]
+
+If not enough buffer space available, but idmap_lookup has triggered
+lookup_fn which calls cache_get and returns successfully. Then we
+missed to call cache_put here which pairs with cache_get.
+
+Fixes: ddd1ea563672 ("nfsd4: use xdr_reserve_space in attribute encoding")
+Signed-off-by: Guoqing Jiang <guoqing.jiang@linux.dev>
+Reviwed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4idmap.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
+index 5e9809aff37eb..717e400b16b86 100644
+--- a/fs/nfsd/nfs4idmap.c
++++ b/fs/nfsd/nfs4idmap.c
+@@ -581,6 +581,7 @@ static __be32 idmap_id_to_name(struct xdr_stream *xdr,
+ .id = id,
+ .type = type,
+ };
++ __be32 status = nfs_ok;
+ __be32 *p;
+ int ret;
+ struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
+@@ -593,12 +594,16 @@ static __be32 idmap_id_to_name(struct xdr_stream *xdr,
+ return nfserrno(ret);
+ ret = strlen(item->name);
+ WARN_ON_ONCE(ret > IDMAP_NAMESZ);
++
+ p = xdr_reserve_space(xdr, ret + 4);
+- if (!p)
+- return nfserr_resource;
+- p = xdr_encode_opaque(p, item->name, ret);
++ if (unlikely(!p)) {
++ status = nfserr_resource;
++ goto out_put;
++ }
++ xdr_encode_opaque(p, item->name, ret);
++out_put:
+ cache_put(&item->h, nn->idtoname_cache);
+- return 0;
++ return status;
+ }
+
+ static bool
+--
+2.43.0
+
--- /dev/null
+From 03452a672a5f3028da994a3c670a10b7fe280e54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jul 2024 09:05:32 -0400
+Subject: nfsd: fix refcount leak when file is unhashed after being found
+
+From: Jeff Layton <jlayton@kernel.org>
+
+[ Upstream commit 8a7926176378460e0d91e02b03f0ff20a8709a60 ]
+
+If we wait_for_construction and find that the file is no longer hashed,
+and we're going to retry the open, the old nfsd_file reference is
+currently leaked. Put the reference before retrying.
+
+Fixes: c6593366c0bf ("nfsd: don't kill nfsd_files because of lease break error")
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Tested-by: Youzhong Yang <youzhong@gmail.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/filecache.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c
+index 96a2be833b20b..31169f0cc3d74 100644
+--- a/fs/nfsd/filecache.c
++++ b/fs/nfsd/filecache.c
+@@ -1054,6 +1054,7 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
+ status = nfserr_jukebox;
+ goto construction_err;
+ }
++ nfsd_file_put(nf);
+ open_retry = false;
+ goto retry;
+ }
+--
+2.43.0
+
--- /dev/null
+From ad020d9ccbade09263fd754c9a4f681d101e6541 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jul 2024 15:11:13 -0400
+Subject: nfsd: remove unneeded EEXIST error check in nfsd_do_file_acquire
+
+From: Jeff Layton <jlayton@kernel.org>
+
+[ Upstream commit 81a95c2b1d605743220f28db04b8da13a65c4059 ]
+
+Given that we do the search and insertion while holding the i_lock, I
+don't think it's possible for us to get EEXIST here. Remove this case.
+
+Fixes: c6593366c0bf ("nfsd: don't kill nfsd_files because of lease break error")
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Tested-by: Youzhong Yang <youzhong@gmail.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/filecache.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c
+index 615ea8324911e..96a2be833b20b 100644
+--- a/fs/nfsd/filecache.c
++++ b/fs/nfsd/filecache.c
+@@ -1040,8 +1040,6 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
+ if (likely(ret == 0))
+ goto open_file;
+
+- if (ret == -EEXIST)
+- goto retry;
+ trace_nfsd_file_insert_err(rqstp, inode, may_flags, ret);
+ status = nfserr_jukebox;
+ goto construction_err;
+--
+2.43.0
+
--- /dev/null
+From 4d536d2b523c759dfa0f59ed2cd4edd4cb9046e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Sep 2024 19:14:46 +0800
+Subject: nfsd: return -EINVAL when namelen is 0
+
+From: Li Lingfeng <lilingfeng3@huawei.com>
+
+[ Upstream commit 22451a16b7ab7debefce660672566be887db1637 ]
+
+When we have a corrupted main.sqlite in /var/lib/nfs/nfsdcld/, it may
+result in namelen being 0, which will cause memdup_user() to return
+ZERO_SIZE_PTR.
+When we access the name.data that has been assigned the value of
+ZERO_SIZE_PTR in nfs4_client_to_reclaim(), null pointer dereference is
+triggered.
+
+[ T1205] ==================================================================
+[ T1205] BUG: KASAN: null-ptr-deref in nfs4_client_to_reclaim+0xe9/0x260
+[ T1205] Read of size 1 at addr 0000000000000010 by task nfsdcld/1205
+[ T1205]
+[ T1205] CPU: 11 PID: 1205 Comm: nfsdcld Not tainted 5.10.0-00003-g2c1423731b8d #406
+[ T1205] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20190727_073836-buildvm-ppc64le-16.ppc.fedoraproject.org-3.fc31 04/01/2014
+[ T1205] Call Trace:
+[ T1205] dump_stack+0x9a/0xd0
+[ T1205] ? nfs4_client_to_reclaim+0xe9/0x260
+[ T1205] __kasan_report.cold+0x34/0x84
+[ T1205] ? nfs4_client_to_reclaim+0xe9/0x260
+[ T1205] kasan_report+0x3a/0x50
+[ T1205] nfs4_client_to_reclaim+0xe9/0x260
+[ T1205] ? nfsd4_release_lockowner+0x410/0x410
+[ T1205] cld_pipe_downcall+0x5ca/0x760
+[ T1205] ? nfsd4_cld_tracking_exit+0x1d0/0x1d0
+[ T1205] ? down_write_killable_nested+0x170/0x170
+[ T1205] ? avc_policy_seqno+0x28/0x40
+[ T1205] ? selinux_file_permission+0x1b4/0x1e0
+[ T1205] rpc_pipe_write+0x84/0xb0
+[ T1205] vfs_write+0x143/0x520
+[ T1205] ksys_write+0xc9/0x170
+[ T1205] ? __ia32_sys_read+0x50/0x50
+[ T1205] ? ktime_get_coarse_real_ts64+0xfe/0x110
+[ T1205] ? ktime_get_coarse_real_ts64+0xa2/0x110
+[ T1205] do_syscall_64+0x33/0x40
+[ T1205] entry_SYSCALL_64_after_hwframe+0x67/0xd1
+[ T1205] RIP: 0033:0x7fdbdb761bc7
+[ T1205] Code: 0f 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b7 0f 1f 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 514
+[ T1205] RSP: 002b:00007fff8c4b7248 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
+[ T1205] RAX: ffffffffffffffda RBX: 000000000000042b RCX: 00007fdbdb761bc7
+[ T1205] RDX: 000000000000042b RSI: 00007fff8c4b75f0 RDI: 0000000000000008
+[ T1205] RBP: 00007fdbdb761bb0 R08: 0000000000000000 R09: 0000000000000001
+[ T1205] R10: 0000000000000000 R11: 0000000000000246 R12: 000000000000042b
+[ T1205] R13: 0000000000000008 R14: 00007fff8c4b75f0 R15: 0000000000000000
+[ T1205] ==================================================================
+
+Fix it by checking namelen.
+
+Signed-off-by: Li Lingfeng <lilingfeng3@huawei.com>
+Fixes: 74725959c33c ("nfsd: un-deprecate nfsdcld")
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Reviewed-by: Scott Mayhew <smayhew@redhat.com>
+Tested-by: Scott Mayhew <smayhew@redhat.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4recover.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
+index 5d680045fa2c7..2cc543f6c410f 100644
+--- a/fs/nfsd/nfs4recover.c
++++ b/fs/nfsd/nfs4recover.c
+@@ -806,6 +806,10 @@ __cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg,
+ ci = &cmsg->cm_u.cm_clntinfo;
+ if (get_user(namelen, &ci->cc_name.cn_len))
+ return -EFAULT;
++ if (!namelen) {
++ dprintk("%s: namelen should not be zero", __func__);
++ return -EINVAL;
++ }
+ name.data = memdup_user(&ci->cc_name.cn_id, namelen);
+ if (IS_ERR(name.data))
+ return PTR_ERR(name.data);
+@@ -828,6 +832,10 @@ __cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg,
+ cnm = &cmsg->cm_u.cm_name;
+ if (get_user(namelen, &cnm->cn_len))
+ return -EFAULT;
++ if (!namelen) {
++ dprintk("%s: namelen should not be zero", __func__);
++ return -EINVAL;
++ }
+ name.data = memdup_user(&cnm->cn_id, namelen);
+ if (IS_ERR(name.data))
+ return PTR_ERR(name.data);
+--
+2.43.0
+
--- /dev/null
+From 14ee5a59db1c08305c8776187154ee4bc89c74e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Sep 2024 17:13:08 +0900
+Subject: nilfs2: determine empty node blocks as corrupted
+
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+
+[ Upstream commit 111b812d3662f3a1b831d19208f83aa711583fe6 ]
+
+Due to the nature of b-trees, nilfs2 itself and admin tools such as
+mkfs.nilfs2 will never create an intermediate b-tree node block with 0
+child nodes, nor will they delete (key, pointer)-entries that would result
+in such a state. However, it is possible that a b-tree node block is
+corrupted on the backing device and is read with 0 child nodes.
+
+Because operation is not guaranteed if the number of child nodes is 0 for
+intermediate node blocks other than the root node, modify
+nilfs_btree_node_broken(), which performs sanity checks when reading a
+b-tree node block, so that such cases will be judged as metadata
+corruption.
+
+Link: https://lkml.kernel.org/r/20240904081401.16682-3-konishi.ryusuke@gmail.com
+Fixes: 17c76b0104e4 ("nilfs2: B-tree based block mapping")
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Cc: Lizhi Xu <lizhi.xu@windriver.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nilfs2/btree.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
+index fbb6ec56843f4..4de33c534e470 100644
+--- a/fs/nilfs2/btree.c
++++ b/fs/nilfs2/btree.c
+@@ -350,7 +350,7 @@ static int nilfs_btree_node_broken(const struct nilfs_btree_node *node,
+ if (unlikely(level < NILFS_BTREE_LEVEL_NODE_MIN ||
+ level >= NILFS_BTREE_LEVEL_MAX ||
+ (flags & NILFS_BTREE_NODE_ROOT) ||
+- nchildren < 0 ||
++ nchildren <= 0 ||
+ nchildren > NILFS_BTREE_NODE_NCHILDREN_MAX(size))) {
+ nilfs_crit(inode->i_sb,
+ "bad btree node (ino=%lu, blocknr=%llu): level = %d, flags = 0x%x, nchildren = %d",
+--
+2.43.0
+
--- /dev/null
+From f0a2095625be3944d6e81846e411846d2daf2052 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Sep 2024 17:13:07 +0900
+Subject: nilfs2: fix potential null-ptr-deref in nilfs_btree_insert()
+
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+
+[ Upstream commit 9403001ad65ae4f4c5de368bdda3a0636b51d51a ]
+
+Patch series "nilfs2: fix potential issues with empty b-tree nodes".
+
+This series addresses three potential issues with empty b-tree nodes that
+can occur with corrupted filesystem images, including one recently
+discovered by syzbot.
+
+This patch (of 3):
+
+If a b-tree is broken on the device, and the b-tree height is greater than
+2 (the level of the root node is greater than 1) even if the number of
+child nodes of the b-tree root is 0, a NULL pointer dereference occurs in
+nilfs_btree_prepare_insert(), which is called from nilfs_btree_insert().
+
+This is because, when the number of child nodes of the b-tree root is 0,
+nilfs_btree_do_lookup() does not set the block buffer head in any of
+path[x].bp_bh, leaving it as the initial value of NULL, but if the level
+of the b-tree root node is greater than 1, nilfs_btree_get_nonroot_node(),
+which accesses the buffer memory of path[x].bp_bh, is called.
+
+Fix this issue by adding a check to nilfs_btree_root_broken(), which
+performs sanity checks when reading the root node from the device, to
+detect this inconsistency.
+
+Thanks to Lizhi Xu for trying to solve the bug and clarifying the cause
+early on.
+
+Link: https://lkml.kernel.org/r/20240904081401.16682-1-konishi.ryusuke@gmail.com
+Link: https://lkml.kernel.org/r/20240902084101.138971-1-lizhi.xu@windriver.com
+Link: https://lkml.kernel.org/r/20240904081401.16682-2-konishi.ryusuke@gmail.com
+Fixes: 17c76b0104e4 ("nilfs2: B-tree based block mapping")
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Reported-by: syzbot+9bff4c7b992038a7409f@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=9bff4c7b992038a7409f
+Cc: Lizhi Xu <lizhi.xu@windriver.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nilfs2/btree.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
+index 8e3d343b9a793..fbb6ec56843f4 100644
+--- a/fs/nilfs2/btree.c
++++ b/fs/nilfs2/btree.c
+@@ -381,7 +381,8 @@ static int nilfs_btree_root_broken(const struct nilfs_btree_node *node,
+ if (unlikely(level < NILFS_BTREE_LEVEL_NODE_MIN ||
+ level >= NILFS_BTREE_LEVEL_MAX ||
+ nchildren < 0 ||
+- nchildren > NILFS_BTREE_ROOT_NCHILDREN_MAX)) {
++ nchildren > NILFS_BTREE_ROOT_NCHILDREN_MAX ||
++ (nchildren == 0 && level > NILFS_BTREE_LEVEL_NODE_MIN))) {
+ nilfs_crit(inode->i_sb,
+ "bad btree root (ino=%lu): level = %d, flags = 0x%x, nchildren = %d",
+ inode->i_ino, level, flags, nchildren);
+--
+2.43.0
+
--- /dev/null
+From 3604a96e1072d5c5bed1a55dc664f44b42419de9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Sep 2024 17:13:09 +0900
+Subject: nilfs2: fix potential oob read in nilfs_btree_check_delete()
+
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+
+[ Upstream commit f9c96351aa6718b42a9f42eaf7adce0356bdb5e8 ]
+
+The function nilfs_btree_check_delete(), which checks whether degeneration
+to direct mapping occurs before deleting a b-tree entry, causes memory
+access outside the block buffer when retrieving the maximum key if the
+root node has no entries.
+
+This does not usually happen because b-tree mappings with 0 child nodes
+are never created by mkfs.nilfs2 or nilfs2 itself. However, it can happen
+if the b-tree root node read from a device is configured that way, so fix
+this potential issue by adding a check for that case.
+
+Link: https://lkml.kernel.org/r/20240904081401.16682-4-konishi.ryusuke@gmail.com
+Fixes: 17c76b0104e4 ("nilfs2: B-tree based block mapping")
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Cc: Lizhi Xu <lizhi.xu@windriver.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nilfs2/btree.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
+index 4de33c534e470..29f967fb7e9b6 100644
+--- a/fs/nilfs2/btree.c
++++ b/fs/nilfs2/btree.c
+@@ -1659,13 +1659,16 @@ static int nilfs_btree_check_delete(struct nilfs_bmap *btree, __u64 key)
+ int nchildren, ret;
+
+ root = nilfs_btree_get_root(btree);
++ nchildren = nilfs_btree_node_get_nchildren(root);
++ if (unlikely(nchildren == 0))
++ return 0;
++
+ switch (nilfs_btree_height(btree)) {
+ case 2:
+ bh = NULL;
+ node = root;
+ break;
+ case 3:
+- nchildren = nilfs_btree_node_get_nchildren(root);
+ if (nchildren > 1)
+ return 0;
+ ptr = nilfs_btree_node_get_ptr(root, nchildren - 1,
+@@ -1674,12 +1677,12 @@ static int nilfs_btree_check_delete(struct nilfs_bmap *btree, __u64 key)
+ if (ret < 0)
+ return ret;
+ node = (struct nilfs_btree_node *)bh->b_data;
++ nchildren = nilfs_btree_node_get_nchildren(node);
+ break;
+ default:
+ return 0;
+ }
+
+- nchildren = nilfs_btree_node_get_nchildren(node);
+ maxkey = nilfs_btree_node_get_key(node, nchildren - 1);
+ nextmaxkey = (nchildren > 1) ?
+ nilfs_btree_node_get_key(node, nchildren - 2) : 0;
+--
+2.43.0
+
--- /dev/null
+From 10d3049bfa83982ef602e60ce37aeac189ff676f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 31 Aug 2023 20:39:27 +0800
+Subject: ntb: intel: Fix the NULL vs IS_ERR() bug for debugfs_create_dir()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit e229897d373a87ee09ec5cc4ecd4bb2f895fc16b ]
+
+The debugfs_create_dir() function returns error pointers.
+It never returns NULL. So use IS_ERR() to check it.
+
+Fixes: e26a5843f7f5 ("NTB: Split ntb_hw_intel and ntb_transport drivers")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Signed-off-by: Jon Mason <jdmason@kudzu.us>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ntb/hw/intel/ntb_hw_gen1.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/ntb/hw/intel/ntb_hw_gen1.c b/drivers/ntb/hw/intel/ntb_hw_gen1.c
+index 41897167abc71..e0a5744372532 100644
+--- a/drivers/ntb/hw/intel/ntb_hw_gen1.c
++++ b/drivers/ntb/hw/intel/ntb_hw_gen1.c
+@@ -778,7 +778,7 @@ static void ndev_init_debugfs(struct intel_ntb_dev *ndev)
+ ndev->debugfs_dir =
+ debugfs_create_dir(pci_name(ndev->ntb.pdev),
+ debugfs_dir);
+- if (!ndev->debugfs_dir)
++ if (IS_ERR(ndev->debugfs_dir))
+ ndev->debugfs_info = NULL;
+ else
+ ndev->debugfs_info =
+--
+2.43.0
+
--- /dev/null
+From a4aab0781bc798934c2009e4e128f0d894ae102f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Oct 2023 20:45:16 -0700
+Subject: ntb_perf: Fix printk format
+
+From: Max Hawking <maxahawking@sonnenkinder.org>
+
+[ Upstream commit 1501ae7479c8d0f66efdbfdc9ae8d6136cefbd37 ]
+
+The correct printk format is %pa or %pap, but not %pa[p].
+
+Fixes: 99a06056124d ("NTB: ntb_perf: Fix address err in perf_copy_chunk")
+Signed-off-by: Max Hawking <maxahawking@sonnenkinder.org>
+Signed-off-by: Jon Mason <jdmason@kudzu.us>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ntb/test/ntb_perf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/ntb/test/ntb_perf.c b/drivers/ntb/test/ntb_perf.c
+index 65e1e5cf1b29a..5a7a02408166e 100644
+--- a/drivers/ntb/test/ntb_perf.c
++++ b/drivers/ntb/test/ntb_perf.c
+@@ -1227,7 +1227,7 @@ static ssize_t perf_dbgfs_read_info(struct file *filep, char __user *ubuf,
+ "\tOut buffer addr 0x%pK\n", peer->outbuf);
+
+ pos += scnprintf(buf + pos, buf_size - pos,
+- "\tOut buff phys addr %pa[p]\n", &peer->out_phys_addr);
++ "\tOut buff phys addr %pap\n", &peer->out_phys_addr);
+
+ pos += scnprintf(buf + pos, buf_size - pos,
+ "\tOut buffer size %pa\n", &peer->outbuf_size);
+--
+2.43.0
+
--- /dev/null
+From 0966e068b83b421e84389b2eb1b9ad3b651f4833 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Aug 2024 02:32:52 +0530
+Subject: padata: Honor the caller's alignment in case of chunk_size 0
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kamlesh Gurudasani <kamlesh@ti.com>
+
+[ Upstream commit 24cc57d8faaa4060fd58adf810b858fcfb71a02f ]
+
+In the case where we are forcing the ps.chunk_size to be at least 1,
+we are ignoring the caller's alignment.
+
+Move the forcing of ps.chunk_size to be at least 1 before rounding it
+up to caller's alignment, so that caller's alignment is honored.
+
+While at it, use max() to force the ps.chunk_size to be at least 1 to
+improve readability.
+
+Fixes: 6d45e1c948a8 ("padata: Fix possible divide-by-0 panic in padata_mt_helper()")
+Signed-off-by: Kamlesh Gurudasani <kamlesh@ti.com>
+Acked-by: Waiman Long <longman@redhat.com>
+Acked-by: Daniel Jordan <daniel.m.jordan@oracle.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/padata.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/kernel/padata.c b/kernel/padata.c
+index 7c52f9de5d4ec..f567b54d79639 100644
+--- a/kernel/padata.c
++++ b/kernel/padata.c
+@@ -503,9 +503,12 @@ void __init padata_do_multithreaded(struct padata_mt_job *job)
+ * thread function. Load balance large jobs between threads by
+ * increasing the number of chunks, guarantee at least the minimum
+ * chunk size from the caller, and honor the caller's alignment.
++ * Ensure chunk_size is at least 1 to prevent divide-by-0
++ * panic in padata_mt_helper().
+ */
+ ps.chunk_size = job->size / (ps.nworks * load_balance_factor);
+ ps.chunk_size = max(ps.chunk_size, job->min_chunk);
++ ps.chunk_size = max(ps.chunk_size, 1ul);
+ ps.chunk_size = roundup(ps.chunk_size, job->align);
+
+ /*
+--
+2.43.0
+
--- /dev/null
+From f3be6edd04202992a0a347566b2c56a32ad44111 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jul 2024 18:53:26 -0500
+Subject: PCI: keystone: Fix if-statement expression in ks_pcie_quirk()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 6188a1c762eb9bbd444f47696eda77a5eae6207a ]
+
+This code accidentally uses && where || was intended. It potentially
+results in a NULL dereference.
+
+Thus, fix the if-statement expression to use the correct condition.
+
+Fixes: 86f271f22bbb ("PCI: keystone: Add workaround for Errata #i2037 (AM65x SR 1.0)")
+Link: https://lore.kernel.org/linux-pci/1b762a93-e1b2-4af3-8c04-c8843905c279@stanley.mountain
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+[kwilczynski: commit log]
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Siddharth Vadapalli <s-vadapalli@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pci-keystone.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
+index 24031123a5504..80eb0c04bc59d 100644
+--- a/drivers/pci/controller/dwc/pci-keystone.c
++++ b/drivers/pci/controller/dwc/pci-keystone.c
+@@ -589,7 +589,7 @@ static void ks_pcie_quirk(struct pci_dev *dev)
+ */
+ if (pci_match_id(am6_pci_devids, bridge)) {
+ bridge_dev = pci_get_host_bridge_device(dev);
+- if (!bridge_dev && !bridge_dev->parent)
++ if (!bridge_dev || !bridge_dev->parent)
+ return;
+
+ ks_pcie = dev_get_drvdata(bridge_dev->parent);
+--
+2.43.0
+
--- /dev/null
+From 1c3caaa0e1171e02975a9cb8f2dd674f2a733ad1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 May 2024 12:13:35 -0400
+Subject: PCI: xilinx-nwl: Clean up clock on probe failure/removal
+
+From: Sean Anderson <sean.anderson@linux.dev>
+
+[ Upstream commit cfd67903977b13f63340a4eb5a1cc890994f2c62 ]
+
+Make sure we turn off the clock on probe failure and device removal.
+
+Fixes: de0a01f52966 ("PCI: xilinx-nwl: Enable the clock through CCF")
+Link: https://lore.kernel.org/r/20240531161337.864994-6-sean.anderson@linux.dev
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-xilinx-nwl.c | 23 +++++++++++++++++++----
+ 1 file changed, 19 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c
+index e1bcdd2e46484..280c569c5dcb0 100644
+--- a/drivers/pci/controller/pcie-xilinx-nwl.c
++++ b/drivers/pci/controller/pcie-xilinx-nwl.c
+@@ -808,6 +808,7 @@ static int nwl_pcie_probe(struct platform_device *pdev)
+ return -ENODEV;
+
+ pcie = pci_host_bridge_priv(bridge);
++ platform_set_drvdata(pdev, pcie);
+
+ pcie->dev = dev;
+ pcie->ecam_value = NWL_ECAM_VALUE_DEFAULT;
+@@ -831,13 +832,13 @@ static int nwl_pcie_probe(struct platform_device *pdev)
+ err = nwl_pcie_bridge_init(pcie);
+ if (err) {
+ dev_err(dev, "HW Initialization failed\n");
+- return err;
++ goto err_clk;
+ }
+
+ err = nwl_pcie_init_irq_domain(pcie);
+ if (err) {
+ dev_err(dev, "Failed creating IRQ Domain\n");
+- return err;
++ goto err_clk;
+ }
+
+ bridge->sysdata = pcie;
+@@ -847,11 +848,24 @@ static int nwl_pcie_probe(struct platform_device *pdev)
+ err = nwl_pcie_enable_msi(pcie);
+ if (err < 0) {
+ dev_err(dev, "failed to enable MSI support: %d\n", err);
+- return err;
++ goto err_clk;
+ }
+ }
+
+- return pci_host_probe(bridge);
++ err = pci_host_probe(bridge);
++ if (!err)
++ return 0;
++
++err_clk:
++ clk_disable_unprepare(pcie->clk);
++ return err;
++}
++
++static void nwl_pcie_remove(struct platform_device *pdev)
++{
++ struct nwl_pcie *pcie = platform_get_drvdata(pdev);
++
++ clk_disable_unprepare(pcie->clk);
+ }
+
+ static struct platform_driver nwl_pcie_driver = {
+@@ -861,5 +875,6 @@ static struct platform_driver nwl_pcie_driver = {
+ .of_match_table = nwl_pcie_of_match,
+ },
+ .probe = nwl_pcie_probe,
++ .remove_new = nwl_pcie_remove,
+ };
+ builtin_platform_driver(nwl_pcie_driver);
+--
+2.43.0
+
--- /dev/null
+From ccbcd2055a545b84ed32365c62e8ecdc80d6b31c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 May 2024 12:13:33 -0400
+Subject: PCI: xilinx-nwl: Fix register misspelling
+
+From: Sean Anderson <sean.anderson@linux.dev>
+
+[ Upstream commit a437027ae1730b8dc379c75fa0dd7d3036917400 ]
+
+MSIC -> MISC
+
+Fixes: c2a7ff18edcd ("PCI: xilinx-nwl: Expand error logging")
+Link: https://lore.kernel.org/r/20240531161337.864994-4-sean.anderson@linux.dev
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-xilinx-nwl.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c
+index a72b4f9a2b001..e1bcdd2e46484 100644
+--- a/drivers/pci/controller/pcie-xilinx-nwl.c
++++ b/drivers/pci/controller/pcie-xilinx-nwl.c
+@@ -81,8 +81,8 @@
+ #define MSGF_MISC_SR_NON_FATAL_DEV BIT(22)
+ #define MSGF_MISC_SR_FATAL_DEV BIT(23)
+ #define MSGF_MISC_SR_LINK_DOWN BIT(24)
+-#define MSGF_MSIC_SR_LINK_AUTO_BWIDTH BIT(25)
+-#define MSGF_MSIC_SR_LINK_BWIDTH BIT(26)
++#define MSGF_MISC_SR_LINK_AUTO_BWIDTH BIT(25)
++#define MSGF_MISC_SR_LINK_BWIDTH BIT(26)
+
+ #define MSGF_MISC_SR_MASKALL (MSGF_MISC_SR_RXMSG_AVAIL | \
+ MSGF_MISC_SR_RXMSG_OVER | \
+@@ -97,8 +97,8 @@
+ MSGF_MISC_SR_NON_FATAL_DEV | \
+ MSGF_MISC_SR_FATAL_DEV | \
+ MSGF_MISC_SR_LINK_DOWN | \
+- MSGF_MSIC_SR_LINK_AUTO_BWIDTH | \
+- MSGF_MSIC_SR_LINK_BWIDTH)
++ MSGF_MISC_SR_LINK_AUTO_BWIDTH | \
++ MSGF_MISC_SR_LINK_BWIDTH)
+
+ /* Legacy interrupt status mask bits */
+ #define MSGF_LEG_SR_INTA BIT(0)
+@@ -302,10 +302,10 @@ static irqreturn_t nwl_pcie_misc_handler(int irq, void *data)
+ if (misc_stat & MSGF_MISC_SR_FATAL_DEV)
+ dev_err(dev, "Fatal Error Detected\n");
+
+- if (misc_stat & MSGF_MSIC_SR_LINK_AUTO_BWIDTH)
++ if (misc_stat & MSGF_MISC_SR_LINK_AUTO_BWIDTH)
+ dev_info(dev, "Link Autonomous Bandwidth Management Status bit set\n");
+
+- if (misc_stat & MSGF_MSIC_SR_LINK_BWIDTH)
++ if (misc_stat & MSGF_MISC_SR_LINK_BWIDTH)
+ dev_info(dev, "Link Bandwidth Management Status bit set\n");
+
+ /* Clear misc interrupt status */
+--
+2.43.0
+
--- /dev/null
+From 9b5aeaea335555afe1d92f3983d33034915ce1b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Jan 2022 22:13:41 -0800
+Subject: perf evsel: Reduce scope of evsel__ignore_missing_thread
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 1fa497d4c01d497e25131ccdd5def6f24dd1f330 ]
+
+Move to being static.
+
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: John Garry <john.garry@huawei.com>
+Cc: Kajol Jain <kjain@linux.ibm.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
+Cc: Mike Leach <mike.leach@linaro.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Clarke <pc@us.ibm.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Riccardo Mancini <rickyman7@gmail.com>
+Cc: Stephane Eranian <eranian@google.com>
+Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
+Cc: Vineet Singh <vineet.singh@intel.com>
+Cc: coresight@lists.linaro.org
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: zhengjun.xing@intel.com
+Link: https://lore.kernel.org/r/20220105061351.120843-39-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: 79bcd34e0f3d ("perf inject: Fix leader sampling inserting additional samples")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/evsel.c | 8 ++++----
+ tools/perf/util/evsel.h | 4 ----
+ 2 files changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
+index c19a583ca9f66..b5b8f723e577b 100644
+--- a/tools/perf/util/evsel.c
++++ b/tools/perf/util/evsel.c
+@@ -1675,10 +1675,10 @@ static int update_fds(struct evsel *evsel,
+ return 0;
+ }
+
+-bool evsel__ignore_missing_thread(struct evsel *evsel,
+- int nr_cpus, int cpu,
+- struct perf_thread_map *threads,
+- int thread, int err)
++static bool evsel__ignore_missing_thread(struct evsel *evsel,
++ int nr_cpus, int cpu,
++ struct perf_thread_map *threads,
++ int thread, int err)
+ {
+ pid_t ignore_pid = perf_thread_map__pid(threads, thread);
+
+diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
+index 0492cafac4430..461eb0feb5365 100644
+--- a/tools/perf/util/evsel.h
++++ b/tools/perf/util/evsel.h
+@@ -302,10 +302,6 @@ bool evsel__detect_missing_features(struct evsel *evsel);
+ enum rlimit_action { NO_CHANGE, SET_TO_MAX, INCREASED_MAX };
+ bool evsel__increase_rlimit(enum rlimit_action *set_rlimit);
+
+-bool evsel__ignore_missing_thread(struct evsel *evsel,
+- int nr_cpus, int cpu,
+- struct perf_thread_map *threads,
+- int thread, int err);
+ bool evsel__precise_ip_fallback(struct evsel *evsel);
+
+ struct perf_sample;
+--
+2.43.0
+
--- /dev/null
+From 1c8c0880b69bd41952ddf8fca60b7c289713b37c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Jan 2022 22:13:42 -0800
+Subject: perf evsel: Rename variable cpu to index
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 6f844b1fdd3bc3a25995ff83edea32a73bfa72d9 ]
+
+Make naming less error prone.
+
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: John Garry <john.garry@huawei.com>
+Cc: Kajol Jain <kjain@linux.ibm.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
+Cc: Mike Leach <mike.leach@linaro.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Paul Clarke <pc@us.ibm.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Riccardo Mancini <rickyman7@gmail.com>
+Cc: Stephane Eranian <eranian@google.com>
+Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
+Cc: Vineet Singh <vineet.singh@intel.com>
+Cc: coresight@lists.linaro.org
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: zhengjun.xing@intel.com
+Link: https://lore.kernel.org/r/20220105061351.120843-40-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: 79bcd34e0f3d ("perf inject: Fix leader sampling inserting additional samples")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/evsel.c | 83 +++++++++++++++++++++--------------------
+ tools/perf/util/evsel.h | 6 +--
+ tools/perf/util/stat.c | 4 +-
+ tools/perf/util/stat.h | 2 +-
+ 4 files changed, 48 insertions(+), 47 deletions(-)
+
+diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
+index b5b8f723e577b..4f4226f380d1c 100644
+--- a/tools/perf/util/evsel.c
++++ b/tools/perf/util/evsel.c
+@@ -1364,9 +1364,9 @@ int evsel__append_addr_filter(struct evsel *evsel, const char *filter)
+ }
+
+ /* Caller has to clear disabled after going through all CPUs. */
+-int evsel__enable_cpu(struct evsel *evsel, int cpu)
++int evsel__enable_cpu(struct evsel *evsel, int cpu_map_idx)
+ {
+- return perf_evsel__enable_cpu(&evsel->core, cpu);
++ return perf_evsel__enable_cpu(&evsel->core, cpu_map_idx);
+ }
+
+ int evsel__enable(struct evsel *evsel)
+@@ -1379,9 +1379,9 @@ int evsel__enable(struct evsel *evsel)
+ }
+
+ /* Caller has to set disabled after going through all CPUs. */
+-int evsel__disable_cpu(struct evsel *evsel, int cpu)
++int evsel__disable_cpu(struct evsel *evsel, int cpu_map_idx)
+ {
+- return perf_evsel__disable_cpu(&evsel->core, cpu);
++ return perf_evsel__disable_cpu(&evsel->core, cpu_map_idx);
+ }
+
+ int evsel__disable(struct evsel *evsel)
+@@ -1445,7 +1445,7 @@ void evsel__delete(struct evsel *evsel)
+ free(evsel);
+ }
+
+-void evsel__compute_deltas(struct evsel *evsel, int cpu, int thread,
++void evsel__compute_deltas(struct evsel *evsel, int cpu_map_idx, int thread,
+ struct perf_counts_values *count)
+ {
+ struct perf_counts_values tmp;
+@@ -1453,12 +1453,12 @@ void evsel__compute_deltas(struct evsel *evsel, int cpu, int thread,
+ if (!evsel->prev_raw_counts)
+ return;
+
+- if (cpu == -1) {
++ if (cpu_map_idx == -1) {
+ tmp = evsel->prev_raw_counts->aggr;
+ evsel->prev_raw_counts->aggr = *count;
+ } else {
+- tmp = *perf_counts(evsel->prev_raw_counts, cpu, thread);
+- *perf_counts(evsel->prev_raw_counts, cpu, thread) = *count;
++ tmp = *perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread);
++ *perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread) = *count;
+ }
+
+ count->val = count->val - tmp.val;
+@@ -1492,20 +1492,21 @@ static int evsel__read_one(struct evsel *evsel, int cpu, int thread)
+ return perf_evsel__read(&evsel->core, cpu, thread, count);
+ }
+
+-static void evsel__set_count(struct evsel *counter, int cpu, int thread, u64 val, u64 ena, u64 run)
++static void evsel__set_count(struct evsel *counter, int cpu_map_idx, int thread,
++ u64 val, u64 ena, u64 run)
+ {
+ struct perf_counts_values *count;
+
+- count = perf_counts(counter->counts, cpu, thread);
++ count = perf_counts(counter->counts, cpu_map_idx, thread);
+
+ count->val = val;
+ count->ena = ena;
+ count->run = run;
+
+- perf_counts__set_loaded(counter->counts, cpu, thread, true);
++ perf_counts__set_loaded(counter->counts, cpu_map_idx, thread, true);
+ }
+
+-static int evsel__process_group_data(struct evsel *leader, int cpu, int thread, u64 *data)
++static int evsel__process_group_data(struct evsel *leader, int cpu_map_idx, int thread, u64 *data)
+ {
+ u64 read_format = leader->core.attr.read_format;
+ struct sample_read_value *v;
+@@ -1524,7 +1525,7 @@ static int evsel__process_group_data(struct evsel *leader, int cpu, int thread,
+
+ v = (struct sample_read_value *) data;
+
+- evsel__set_count(leader, cpu, thread, v[0].value, ena, run);
++ evsel__set_count(leader, cpu_map_idx, thread, v[0].value, ena, run);
+
+ for (i = 1; i < nr; i++) {
+ struct evsel *counter;
+@@ -1533,7 +1534,7 @@ static int evsel__process_group_data(struct evsel *leader, int cpu, int thread,
+ if (!counter)
+ return -EINVAL;
+
+- evsel__set_count(counter, cpu, thread, v[i].value, ena, run);
++ evsel__set_count(counter, cpu_map_idx, thread, v[i].value, ena, run);
+ }
+
+ return 0;
+@@ -1652,16 +1653,16 @@ static void evsel__remove_fd(struct evsel *pos, int nr_cpus, int nr_threads, int
+ }
+
+ static int update_fds(struct evsel *evsel,
+- int nr_cpus, int cpu_idx,
++ int nr_cpus, int cpu_map_idx,
+ int nr_threads, int thread_idx)
+ {
+ struct evsel *pos;
+
+- if (cpu_idx >= nr_cpus || thread_idx >= nr_threads)
++ if (cpu_map_idx >= nr_cpus || thread_idx >= nr_threads)
+ return -EINVAL;
+
+ evlist__for_each_entry(evsel->evlist, pos) {
+- nr_cpus = pos != evsel ? nr_cpus : cpu_idx;
++ nr_cpus = pos != evsel ? nr_cpus : cpu_map_idx;
+
+ evsel__remove_fd(pos, nr_cpus, nr_threads, thread_idx);
+
+@@ -1676,7 +1677,7 @@ static int update_fds(struct evsel *evsel,
+ }
+
+ static bool evsel__ignore_missing_thread(struct evsel *evsel,
+- int nr_cpus, int cpu,
++ int nr_cpus, int cpu_map_idx,
+ struct perf_thread_map *threads,
+ int thread, int err)
+ {
+@@ -1701,7 +1702,7 @@ static bool evsel__ignore_missing_thread(struct evsel *evsel,
+ * We should remove fd for missing_thread first
+ * because thread_map__remove() will decrease threads->nr.
+ */
+- if (update_fds(evsel, nr_cpus, cpu, threads->nr, thread))
++ if (update_fds(evsel, nr_cpus, cpu_map_idx, threads->nr, thread))
+ return false;
+
+ if (thread_map__remove(threads, thread))
+@@ -1966,9 +1967,9 @@ bool evsel__increase_rlimit(enum rlimit_action *set_rlimit)
+
+ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
+ struct perf_thread_map *threads,
+- int start_cpu, int end_cpu)
++ int start_cpu_map_idx, int end_cpu_map_idx)
+ {
+- int cpu, thread, nthreads;
++ int idx, thread, nthreads;
+ int pid = -1, err, old_errno;
+ enum rlimit_action set_rlimit = NO_CHANGE;
+
+@@ -1995,7 +1996,7 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
+
+ display_attr(&evsel->core.attr);
+
+- for (cpu = start_cpu; cpu < end_cpu; cpu++) {
++ for (idx = start_cpu_map_idx; idx < end_cpu_map_idx; idx++) {
+
+ for (thread = 0; thread < nthreads; thread++) {
+ int fd, group_fd;
+@@ -2006,17 +2007,17 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
+ if (!evsel->cgrp && !evsel->core.system_wide)
+ pid = perf_thread_map__pid(threads, thread);
+
+- group_fd = get_group_fd(evsel, cpu, thread);
++ group_fd = get_group_fd(evsel, idx, thread);
+
+ test_attr__ready();
+
+ pr_debug2_peo("sys_perf_event_open: pid %d cpu %d group_fd %d flags %#lx",
+- pid, cpus->map[cpu], group_fd, evsel->open_flags);
++ pid, cpus->map[idx], group_fd, evsel->open_flags);
+
+- fd = sys_perf_event_open(&evsel->core.attr, pid, cpus->map[cpu],
++ fd = sys_perf_event_open(&evsel->core.attr, pid, cpus->map[idx],
+ group_fd, evsel->open_flags);
+
+- FD(evsel, cpu, thread) = fd;
++ FD(evsel, idx, thread) = fd;
+
+ if (fd < 0) {
+ err = -errno;
+@@ -2026,10 +2027,10 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
+ goto try_fallback;
+ }
+
+- bpf_counter__install_pe(evsel, cpu, fd);
++ bpf_counter__install_pe(evsel, idx, fd);
+
+ if (unlikely(test_attr__enabled)) {
+- test_attr__open(&evsel->core.attr, pid, cpus->map[cpu],
++ test_attr__open(&evsel->core.attr, pid, cpus->map[idx],
+ fd, group_fd, evsel->open_flags);
+ }
+
+@@ -2070,7 +2071,7 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
+ if (evsel__precise_ip_fallback(evsel))
+ goto retry_open;
+
+- if (evsel__ignore_missing_thread(evsel, cpus->nr, cpu, threads, thread, err)) {
++ if (evsel__ignore_missing_thread(evsel, cpus->nr, idx, threads, thread, err)) {
+ /* We just removed 1 thread, so lower the upper nthreads limit. */
+ nthreads--;
+
+@@ -2085,7 +2086,7 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
+ if (err == -EMFILE && evsel__increase_rlimit(&set_rlimit))
+ goto retry_open;
+
+- if (err != -EINVAL || cpu > 0 || thread > 0)
++ if (err != -EINVAL || idx > 0 || thread > 0)
+ goto out_close;
+
+ if (evsel__detect_missing_features(evsel))
+@@ -2097,12 +2098,12 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
+ old_errno = errno;
+ do {
+ while (--thread >= 0) {
+- if (FD(evsel, cpu, thread) >= 0)
+- close(FD(evsel, cpu, thread));
+- FD(evsel, cpu, thread) = -1;
++ if (FD(evsel, idx, thread) >= 0)
++ close(FD(evsel, idx, thread));
++ FD(evsel, idx, thread) = -1;
+ }
+ thread = nthreads;
+- } while (--cpu >= 0);
++ } while (--idx >= 0);
+ errno = old_errno;
+ return err;
+ }
+@@ -2119,13 +2120,13 @@ void evsel__close(struct evsel *evsel)
+ perf_evsel__free_id(&evsel->core);
+ }
+
+-int evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus, int cpu)
++int evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus, int cpu_map_idx)
+ {
+- if (cpu == -1)
++ if (cpu_map_idx == -1)
+ return evsel__open_cpu(evsel, cpus, NULL, 0,
+ cpus ? cpus->nr : 1);
+
+- return evsel__open_cpu(evsel, cpus, NULL, cpu, cpu + 1);
++ return evsel__open_cpu(evsel, cpus, NULL, cpu_map_idx, cpu_map_idx + 1);
+ }
+
+ int evsel__open_per_thread(struct evsel *evsel, struct perf_thread_map *threads)
+@@ -2872,15 +2873,15 @@ struct perf_env *evsel__env(struct evsel *evsel)
+
+ static int store_evsel_ids(struct evsel *evsel, struct evlist *evlist)
+ {
+- int cpu, thread;
++ int cpu_map_idx, thread;
+
+- for (cpu = 0; cpu < xyarray__max_x(evsel->core.fd); cpu++) {
++ for (cpu_map_idx = 0; cpu_map_idx < xyarray__max_x(evsel->core.fd); cpu_map_idx++) {
+ for (thread = 0; thread < xyarray__max_y(evsel->core.fd);
+ thread++) {
+- int fd = FD(evsel, cpu, thread);
++ int fd = FD(evsel, cpu_map_idx, thread);
+
+ if (perf_evlist__id_add_fd(&evlist->core, &evsel->core,
+- cpu, thread, fd) < 0)
++ cpu_map_idx, thread, fd) < 0)
+ return -1;
+ }
+ }
+diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
+index 461eb0feb5365..9e89dc02a116e 100644
+--- a/tools/perf/util/evsel.h
++++ b/tools/perf/util/evsel.h
+@@ -285,12 +285,12 @@ void arch_evsel__set_sample_weight(struct evsel *evsel);
+ int evsel__set_filter(struct evsel *evsel, const char *filter);
+ int evsel__append_tp_filter(struct evsel *evsel, const char *filter);
+ int evsel__append_addr_filter(struct evsel *evsel, const char *filter);
+-int evsel__enable_cpu(struct evsel *evsel, int cpu);
++int evsel__enable_cpu(struct evsel *evsel, int cpu_map_idx);
+ int evsel__enable(struct evsel *evsel);
+ int evsel__disable(struct evsel *evsel);
+-int evsel__disable_cpu(struct evsel *evsel, int cpu);
++int evsel__disable_cpu(struct evsel *evsel, int cpu_map_idx);
+
+-int evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus, int cpu);
++int evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus, int cpu_map_idx);
+ int evsel__open_per_thread(struct evsel *evsel, struct perf_thread_map *threads);
+ int evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus,
+ struct perf_thread_map *threads);
+diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
+index 5a0b3db1cab11..5f0e2ac91cea7 100644
+--- a/tools/perf/util/stat.c
++++ b/tools/perf/util/stat.c
+@@ -531,7 +531,7 @@ size_t perf_event__fprintf_stat_config(union perf_event *event, FILE *fp)
+ int create_perf_stat_counter(struct evsel *evsel,
+ struct perf_stat_config *config,
+ struct target *target,
+- int cpu)
++ int cpu_map_idx)
+ {
+ struct perf_event_attr *attr = &evsel->core.attr;
+ struct evsel *leader = evsel__leader(evsel);
+@@ -581,7 +581,7 @@ int create_perf_stat_counter(struct evsel *evsel,
+ }
+
+ if (target__has_cpu(target) && !target__has_per_thread(target))
+- return evsel__open_per_cpu(evsel, evsel__cpus(evsel), cpu);
++ return evsel__open_per_cpu(evsel, evsel__cpus(evsel), cpu_map_idx);
+
+ return evsel__open_per_thread(evsel, evsel->core.threads);
+ }
+diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
+index 977616cf69e46..5b7a5aeee1c1c 100644
+--- a/tools/perf/util/stat.h
++++ b/tools/perf/util/stat.h
+@@ -248,7 +248,7 @@ size_t perf_event__fprintf_stat_config(union perf_event *event, FILE *fp);
+ int create_perf_stat_counter(struct evsel *evsel,
+ struct perf_stat_config *config,
+ struct target *target,
+- int cpu);
++ int cpu_map_idx);
+ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *config,
+ struct target *_target, struct timespec *ts, int argc, const char **argv);
+
+--
+2.43.0
+
--- /dev/null
+From 4204dd342041d4d6f9d9950685b6de61fc0b46d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Jul 2024 15:06:20 -0700
+Subject: perf inject: Fix leader sampling inserting additional samples
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 79bcd34e0f3da39fda841406ccc957405e724852 ]
+
+The processing of leader samples would turn an individual sample with
+a group of read values into multiple samples. 'perf inject' would pass
+through the additional samples increasing the output data file size:
+
+ $ perf record -g -e "{instructions,cycles}:S" -o perf.orig.data true
+ $ perf script -D -i perf.orig.data | sed -e 's/perf.orig.data/perf.data/g' > orig.txt
+ $ perf inject -i perf.orig.data -o perf.new.data
+ $ perf script -D -i perf.new.data | sed -e 's/perf.new.data/perf.data/g' > new.txt
+ $ diff -u orig.txt new.txt
+ --- orig.txt 2024-07-29 14:29:40.606576769 -0700
+ +++ new.txt 2024-07-29 14:30:04.142737434 -0700
+ ...
+ -0xc550@perf.data [0x30]: event: 3
+ +0xc550@perf.data [0xd0]: event: 9
+ +.
+ +. ... raw event: size 208 bytes
+ +. 0000: 09 00 00 00 01 00 d0 00 fc 72 01 86 ff ff ff ff .........r......
+ +. 0010: 74 7d 2c 00 74 7d 2c 00 fb c3 79 f9 ba d5 05 00 t},.t},...y.....
+ +. 0020: e6 cb 1a 00 00 00 00 00 01 00 00 00 00 00 00 00 ................
+ +. 0030: 02 00 00 00 00 00 00 00 76 01 00 00 00 00 00 00 ........v.......
+ +. 0040: e6 cb 1a 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ +. 0050: 62 18 00 00 00 00 00 00 f6 cb 1a 00 00 00 00 00 b...............
+ +. 0060: 00 00 00 00 00 00 00 00 0c 00 00 00 00 00 00 00 ................
+ +. 0070: 80 ff ff ff ff ff ff ff fc 72 01 86 ff ff ff ff .........r......
+ +. 0080: f3 0e 6e 85 ff ff ff ff 0c cb 7f 85 ff ff ff ff ..n.............
+ +. 0090: bc f2 87 85 ff ff ff ff 44 af 7f 85 ff ff ff ff ........D.......
+ +. 00a0: bd be 7f 85 ff ff ff ff 26 d0 7f 85 ff ff ff ff ........&.......
+ +. 00b0: 6d a4 ff 85 ff ff ff ff ea 00 20 86 ff ff ff ff m......... .....
+ +. 00c0: 00 fe ff ff ff ff ff ff 57 14 4f 43 fc 7e 00 00 ........W.OC.~..
+ +
+ +1642373909693435 0xc550 [0xd0]: PERF_RECORD_SAMPLE(IP, 0x1): 2915700/2915700: 0xffffffff860172fc period: 1 addr: 0
+ +... FP chain: nr:12
+ +..... 0: ffffffffffffff80
+ +..... 1: ffffffff860172fc
+ +..... 2: ffffffff856e0ef3
+ +..... 3: ffffffff857fcb0c
+ +..... 4: ffffffff8587f2bc
+ +..... 5: ffffffff857faf44
+ +..... 6: ffffffff857fbebd
+ +..... 7: ffffffff857fd026
+ +..... 8: ffffffff85ffa46d
+ +..... 9: ffffffff862000ea
+ +..... 10: fffffffffffffe00
+ +..... 11: 00007efc434f1457
+ +... sample_read:
+ +.... group nr 2
+ +..... id 00000000001acbe6, value 0000000000000176, lost 0
+ +..... id 00000000001acbf6, value 0000000000001862, lost 0
+ +
+ +0xc620@perf.data [0x30]: event: 3
+ ...
+
+This behavior is incorrect as in the case above 'perf inject' should
+have done nothing. Fix this behavior by disabling separating samples
+for a tool that requests it. Only request this for `perf inject` so as
+to not affect other perf tools. With the patch and the test above
+there are no differences between the orig.txt and new.txt.
+
+Fixes: e4caec0d1af3d608 ("perf evsel: Add PERF_SAMPLE_READ sample related processing")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20240729220620.2957754-1-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-inject.c | 1 +
+ tools/perf/util/session.c | 3 +++
+ tools/perf/util/tool.h | 1 +
+ 3 files changed, 5 insertions(+)
+
+diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
+index 8e7a65a8d86ed..2e9d81a16133c 100644
+--- a/tools/perf/builtin-inject.c
++++ b/tools/perf/builtin-inject.c
+@@ -910,6 +910,7 @@ int cmd_inject(int argc, const char **argv)
+ .feature = perf_event__repipe_op2_synth,
+ .compressed = perf_event__repipe_op4_synth,
+ .auxtrace = perf_event__repipe_auxtrace,
++ .dont_split_sample_group = true,
+ },
+ .input_name = "-",
+ .samples = LIST_HEAD_INIT(inject.samples),
+diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
+index 7ba9dd1402ed2..60c44cb33d4a2 100644
+--- a/tools/perf/util/session.c
++++ b/tools/perf/util/session.c
+@@ -1453,6 +1453,9 @@ static int deliver_sample_group(struct evlist *evlist,
+ int ret = -EINVAL;
+ struct sample_read_value *v = sample->read.group.values;
+
++ if (tool->dont_split_sample_group)
++ return deliver_sample_value(evlist, tool, event, sample, v, machine);
++
+ sample_read_group__for_each(v, sample->read.group.nr, read_format) {
+ ret = deliver_sample_value(evlist, tool, event, sample, v,
+ machine);
+diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h
+index bbbc0dcd461ff..504bed227d1e1 100644
+--- a/tools/perf/util/tool.h
++++ b/tools/perf/util/tool.h
+@@ -82,6 +82,7 @@ struct perf_tool {
+ bool namespace_events;
+ bool cgroup_events;
+ bool no_warn;
++ bool dont_split_sample_group;
+ enum show_feature_header show_feat_hdr;
+ };
+
+--
+2.43.0
+
--- /dev/null
+From 9ff594a1ea4a25df042da9b7c22a0adb9a5c8543 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jul 2024 16:55:01 -0700
+Subject: perf mem: Free the allocated sort string, fixing a leak
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit 3da209bb1177462b6fe8e3021a5527a5a49a9336 ]
+
+The get_sort_order() returns either a new string (from strdup) or NULL
+but it never gets freed.
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Fixes: 2e7f545096f954a9 ("perf mem: Factor out a function to generate sort order")
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: https://lore.kernel.org/r/20240731235505.710436-3-namhyung@kernel.org
+[ Added Fixes tag ]
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-mem.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
+index fcf65a59bea21..f0a452338e642 100644
+--- a/tools/perf/builtin-mem.c
++++ b/tools/perf/builtin-mem.c
+@@ -358,6 +358,7 @@ static int report_events(int argc, const char **argv, struct perf_mem *mem)
+ rep_argv[i] = argv[j];
+
+ ret = cmd_report(i, rep_argv);
++ free(new_sort_order);
+ free(rep_argv);
+ return ret;
+ }
+--
+2.43.0
+
--- /dev/null
+From 8f4e8fd7936fc362fbe0234fd96bba1ac33cc891 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Aug 2024 10:35:33 +0800
+Subject: perf sched timehist: Fix missing free of session in
+ perf_sched__timehist()
+
+From: Yang Jihong <yangjihong@bytedance.com>
+
+[ Upstream commit 6bdf5168b6fb19541b0c1862bdaa596d116c7bfb ]
+
+When perf_time__parse_str() fails in perf_sched__timehist(),
+need to free session that was previously created, fix it.
+
+Fixes: 853b74071110bed3 ("perf sched timehist: Add option to specify time window of interest")
+Signed-off-by: Yang Jihong <yangjihong@bytedance.com>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: David Ahern <dsa@cumulusnetworks.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20240806023533.1316348-1-yangjihong@bytedance.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-sched.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
+index 635a6b5a9ec97..7ef1fa6821ae3 100644
+--- a/tools/perf/builtin-sched.c
++++ b/tools/perf/builtin-sched.c
+@@ -3027,7 +3027,8 @@ static int perf_sched__timehist(struct perf_sched *sched)
+
+ if (perf_time__parse_str(&sched->ptime, sched->time_str) != 0) {
+ pr_err("Invalid time string\n");
+- return -EINVAL;
++ err = -EINVAL;
++ goto out;
+ }
+
+ if (timehist_check_attr(sched, evlist) != 0)
+--
+2.43.0
+
--- /dev/null
+From e99e0b54c2c336540ae1aa2f3cd6917cbb803cd9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Aug 2024 10:47:20 +0800
+Subject: perf sched timehist: Fixed timestamp error when unable to confirm
+ event sched_in time
+
+From: Yang Jihong <yangjihong@bytedance.com>
+
+[ Upstream commit 39c243411bdb8fb35777adf49ee32549633c4e12 ]
+
+If sched_in event for current task is not recorded, sched_in timestamp
+will be set to end_time of time window interest, causing an error in
+timestamp show. In this case, we choose to ignore this event.
+
+Test scenario:
+
+ perf[1229608] does not record the first sched_in event, run time and sch delay are both 0
+
+ # perf sched timehist
+ Samples of sched_switch event do not have callchains.
+ time cpu task name wait time sch delay run time
+ [tid/pid] (msec) (msec) (msec)
+ --------------- ------ ------------------------------ --------- --------- ---------
+ 2090450.763231 [0000] perf[1229608] 0.000 0.000 0.000
+ 2090450.763235 [0000] migration/0[15] 0.000 0.001 0.003
+ 2090450.763263 [0001] perf[1229608] 0.000 0.000 0.000
+ 2090450.763268 [0001] migration/1[21] 0.000 0.001 0.004
+ 2090450.763302 [0002] perf[1229608] 0.000 0.000 0.000
+ 2090450.763309 [0002] migration/2[27] 0.000 0.001 0.007
+ 2090450.763338 [0003] perf[1229608] 0.000 0.000 0.000
+ 2090450.763343 [0003] migration/3[33] 0.000 0.001 0.004
+
+Before:
+
+ arbitrarily specify a time window of interest, timestamp will be set to an incorrect value
+
+ # perf sched timehist --time 100,200
+ Samples of sched_switch event do not have callchains.
+ time cpu task name wait time sch delay run time
+ [tid/pid] (msec) (msec) (msec)
+ --------------- ------ ------------------------------ --------- --------- ---------
+ 200.000000 [0000] perf[1229608] 0.000 0.000 0.000
+ 200.000000 [0001] perf[1229608] 0.000 0.000 0.000
+ 200.000000 [0002] perf[1229608] 0.000 0.000 0.000
+ 200.000000 [0003] perf[1229608] 0.000 0.000 0.000
+ 200.000000 [0004] perf[1229608] 0.000 0.000 0.000
+ 200.000000 [0005] perf[1229608] 0.000 0.000 0.000
+ 200.000000 [0006] perf[1229608] 0.000 0.000 0.000
+ 200.000000 [0007] perf[1229608] 0.000 0.000 0.000
+
+ After:
+
+ # perf sched timehist --time 100,200
+ Samples of sched_switch event do not have callchains.
+ time cpu task name wait time sch delay run time
+ [tid/pid] (msec) (msec) (msec)
+ --------------- ------ ------------------------------ --------- --------- ---------
+
+Fixes: 853b74071110bed3 ("perf sched timehist: Add option to specify time window of interest")
+Signed-off-by: Yang Jihong <yangjihong@bytedance.com>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: David Ahern <dsa@cumulusnetworks.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20240819024720.2405244-1-yangjihong@bytedance.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-sched.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
+index 7ef1fa6821ae3..19e96141e7b42 100644
+--- a/tools/perf/builtin-sched.c
++++ b/tools/perf/builtin-sched.c
+@@ -2577,9 +2577,12 @@ static int timehist_sched_change_event(struct perf_tool *tool,
+ * - previous sched event is out of window - we are done
+ * - sample time is beyond window user cares about - reset it
+ * to close out stats for time window interest
++ * - If tprev is 0, that is, sched_in event for current task is
++ * not recorded, cannot determine whether sched_in event is
++ * within time window interest - ignore it
+ */
+ if (ptime->end) {
+- if (tprev > ptime->end)
++ if (!tprev || tprev > ptime->end)
+ goto out;
+
+ if (t > ptime->end)
+--
+2.43.0
+
--- /dev/null
+From 3cf002e2724e30205478df45fb91e8df072c4fce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Oct 2021 17:07:14 +0530
+Subject: perf test sample-parsing: Add endian test for struct branch_flags
+
+From: Madhavan Srinivasan <maddy@linux.ibm.com>
+
+[ Upstream commit 10269a2ca2b08cbdda9232771e59ba901b87a074 ]
+
+Extend the sample-parsing test to include a branch_flag bitfield-endian
+swap test.
+
+This patch adds a include for "util/trace-event.h" in the sample-parsing
+test for importing tep_is_bigendian() and extends samples_same() to
+include "needs_swap" to detect/enable check for bitfield-endian swap.
+
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Acked-by: Jiri Olsa <jolsa@redhat.com>
+Cc: Athira Jajeev <atrajeev@linux.vnet.ibm.com>
+Cc: Kajol Jain <kjain@linux.ibm.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Michael Ellerman <michael@ellerman.id.au>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: http://lore.kernel.org/lkml/20211028113714.600549-2-maddy@linux.ibm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: 79bcd34e0f3d ("perf inject: Fix leader sampling inserting additional samples")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/sample-parsing.c | 43 +++++++++++++++++++++++++++----
+ 1 file changed, 38 insertions(+), 5 deletions(-)
+
+diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c
+index 8fd8a4ef97da1..c83a115141291 100644
+--- a/tools/perf/tests/sample-parsing.c
++++ b/tools/perf/tests/sample-parsing.c
+@@ -13,6 +13,7 @@
+ #include "evsel.h"
+ #include "debug.h"
+ #include "util/synthetic-events.h"
++#include "util/trace-event.h"
+
+ #include "tests.h"
+
+@@ -30,9 +31,18 @@
+ } \
+ } while (0)
+
++/*
++ * Hardcode the expected values for branch_entry flags.
++ * These are based on the input value (213) specified
++ * in branch_stack variable.
++ */
++#define BS_EXPECTED_BE 0xa00d000000000000
++#define BS_EXPECTED_LE 0xd5000000
++#define FLAG(s) s->branch_stack->entries[i].flags
++
+ static bool samples_same(const struct perf_sample *s1,
+ const struct perf_sample *s2,
+- u64 type, u64 read_format)
++ u64 type, u64 read_format, bool needs_swap)
+ {
+ size_t i;
+
+@@ -100,8 +110,14 @@ static bool samples_same(const struct perf_sample *s1,
+ if (type & PERF_SAMPLE_BRANCH_STACK) {
+ COMP(branch_stack->nr);
+ COMP(branch_stack->hw_idx);
+- for (i = 0; i < s1->branch_stack->nr; i++)
+- MCOMP(branch_stack->entries[i]);
++ for (i = 0; i < s1->branch_stack->nr; i++) {
++ if (needs_swap)
++ return ((tep_is_bigendian()) ?
++ (FLAG(s2).value == BS_EXPECTED_BE) :
++ (FLAG(s2).value == BS_EXPECTED_LE));
++ else
++ MCOMP(branch_stack->entries[i]);
++ }
+ }
+
+ if (type & PERF_SAMPLE_REGS_USER) {
+@@ -248,7 +264,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
+ },
+ };
+ struct sample_read_value values[] = {{1, 5}, {9, 3}, {2, 7}, {6, 4},};
+- struct perf_sample sample_out;
++ struct perf_sample sample_out, sample_out_endian;
+ size_t i, sz, bufsz;
+ int err, ret = -1;
+
+@@ -313,12 +329,29 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
+ goto out_free;
+ }
+
+- if (!samples_same(&sample, &sample_out, sample_type, read_format)) {
++ if (!samples_same(&sample, &sample_out, sample_type, read_format, evsel.needs_swap)) {
+ pr_debug("parsing failed for sample_type %#"PRIx64"\n",
+ sample_type);
+ goto out_free;
+ }
+
++ if (sample_type == PERF_SAMPLE_BRANCH_STACK) {
++ evsel.needs_swap = true;
++ evsel.sample_size = __evsel__sample_size(sample_type);
++ err = evsel__parse_sample(&evsel, event, &sample_out_endian);
++ if (err) {
++ pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
++ "evsel__parse_sample", sample_type, err);
++ goto out_free;
++ }
++
++ if (!samples_same(&sample, &sample_out_endian, sample_type, read_format, evsel.needs_swap)) {
++ pr_debug("parsing failed for sample_type %#"PRIx64"\n",
++ sample_type);
++ goto out_free;
++ }
++ }
++
+ ret = 0;
+ out_free:
+ free(event);
+--
+2.43.0
+
--- /dev/null
+From 1358875a332f869d07e2ac735ad612702c3939de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 31 Aug 2024 00:04:11 -0700
+Subject: perf time-utils: Fix 32-bit nsec parsing
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 38e2648a81204c9fc5b4c87a8ffce93a6ed91b65 ]
+
+The "time utils" test fails in 32-bit builds:
+ ...
+ parse_nsec_time("18446744073.709551615")
+ Failed. ptime 4294967295709551615 expected 18446744073709551615
+ ...
+
+Switch strtoul to strtoull as an unsigned long in 32-bit build isn't
+64-bits.
+
+Fixes: c284d669a20d408b ("perf tools: Move parse_nsec_time to time-utils.c")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Cc: Chaitanya S Prakash <chaitanyas.prakash@arm.com>
+Cc: Colin Ian King <colin.i.king@gmail.com>
+Cc: David Ahern <dsa@cumulusnetworks.com>
+Cc: Dominique Martinet <asmadeus@codewreck.org>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@linaro.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: John Garry <john.g.garry@oracle.com>
+Cc: Junhao He <hejunhao3@huawei.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Yang Jihong <yangjihong@bytedance.com>
+Link: https://lore.kernel.org/r/20240831070415.506194-3-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/time-utils.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/util/time-utils.c b/tools/perf/util/time-utils.c
+index 3024439216816..1b91ccd4d5234 100644
+--- a/tools/perf/util/time-utils.c
++++ b/tools/perf/util/time-utils.c
+@@ -20,7 +20,7 @@ int parse_nsec_time(const char *str, u64 *ptime)
+ u64 time_sec, time_nsec;
+ char *end;
+
+- time_sec = strtoul(str, &end, 10);
++ time_sec = strtoull(str, &end, 10);
+ if (*end != '.' && *end != '\0')
+ return -1;
+
+@@ -38,7 +38,7 @@ int parse_nsec_time(const char *str, u64 *ptime)
+ for (i = strlen(nsec_buf); i < 9; i++)
+ nsec_buf[i] = '0';
+
+- time_nsec = strtoul(nsec_buf, &end, 10);
++ time_nsec = strtoull(nsec_buf, &end, 10);
+ if (*end != '\0')
+ return -1;
+ } else
+--
+2.43.0
+
--- /dev/null
+From 174aa0b3d67756588b5050e01a4075eb6fdaec55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Aug 2022 17:36:44 -0700
+Subject: perf tools: Support reading PERF_FORMAT_LOST
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit f52679b78877f17e95a317e18a4c9c46cc3d845a ]
+
+The recent kernel added lost count can be read from either read(2) or
+ring buffer data with PERF_SAMPLE_READ. As it's a variable length data
+we need to access it according to the format info.
+
+But for perf tools use cases, PERF_FORMAT_ID is always set. So we can
+only check PERF_FORMAT_LOST bit to determine the data format.
+
+Add sample_read_value_size() and next_sample_read_value() helpers to
+make it a bit easier to access. Use them in all places where it reads
+the struct sample_read_value.
+
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Acked-by: Jiri Olsa <jolsa@kernel.org>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20220819003644.508916-5-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Stable-dep-of: 79bcd34e0f3d ("perf inject: Fix leader sampling inserting additional samples")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/sample-parsing.c | 14 +++++---
+ tools/perf/util/event.h | 21 ++++++++++-
+ tools/perf/util/evsel.c | 29 +++++++++------
+ .../scripting-engines/trace-event-python.c | 19 +++++++---
+ tools/perf/util/session.c | 35 +++++++++++--------
+ tools/perf/util/synthetic-events.c | 32 +++++++++++++----
+ 6 files changed, 108 insertions(+), 42 deletions(-)
+
+diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c
+index c83a115141291..ac2c21d402a4b 100644
+--- a/tools/perf/tests/sample-parsing.c
++++ b/tools/perf/tests/sample-parsing.c
+@@ -86,10 +86,15 @@ static bool samples_same(const struct perf_sample *s1,
+ COMP(read.time_running);
+ /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
+ if (read_format & PERF_FORMAT_GROUP) {
+- for (i = 0; i < s1->read.group.nr; i++)
+- MCOMP(read.group.values[i]);
++ for (i = 0; i < s1->read.group.nr; i++) {
++ /* FIXME: check values without LOST */
++ if (read_format & PERF_FORMAT_LOST)
++ MCOMP(read.group.values[i]);
++ }
+ } else {
+ COMP(read.one.id);
++ if (read_format & PERF_FORMAT_LOST)
++ COMP(read.one.lost);
+ }
+ }
+
+@@ -263,7 +268,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
+ .data = (void *)aux_data,
+ },
+ };
+- struct sample_read_value values[] = {{1, 5}, {9, 3}, {2, 7}, {6, 4},};
++ struct sample_read_value values[] = {{1, 5, 0}, {9, 3, 0}, {2, 7, 0}, {6, 4, 1},};
+ struct perf_sample sample_out, sample_out_endian;
+ size_t i, sz, bufsz;
+ int err, ret = -1;
+@@ -286,6 +291,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
+ } else {
+ sample.read.one.value = 0x08789faeb786aa87ULL;
+ sample.read.one.id = 99;
++ sample.read.one.lost = 1;
+ }
+
+ sz = perf_event__sample_event_size(&sample, sample_type, read_format);
+@@ -370,7 +376,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
+ */
+ int test__sample_parsing(struct test *test __maybe_unused, int subtest __maybe_unused)
+ {
+- const u64 rf[] = {4, 5, 6, 7, 12, 13, 14, 15};
++ const u64 rf[] = {4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 28, 29, 30, 31};
+ u64 sample_type;
+ u64 sample_regs;
+ size_t i;
+diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
+index 19ad64f2bd830..144c82f8e7ffd 100644
+--- a/tools/perf/util/event.h
++++ b/tools/perf/util/event.h
+@@ -62,7 +62,8 @@ struct stack_dump {
+
+ struct sample_read_value {
+ u64 value;
+- u64 id;
++ u64 id; /* only if PERF_FORMAT_ID */
++ u64 lost; /* only if PERF_FORMAT_LOST */
+ };
+
+ struct sample_read {
+@@ -77,6 +78,24 @@ struct sample_read {
+ };
+ };
+
++static inline size_t sample_read_value_size(u64 read_format)
++{
++ /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
++ if (read_format & PERF_FORMAT_LOST)
++ return sizeof(struct sample_read_value);
++ else
++ return offsetof(struct sample_read_value, lost);
++}
++
++static inline struct sample_read_value *
++next_sample_read_value(struct sample_read_value *v, u64 read_format)
++{
++ return (void *)v + sample_read_value_size(read_format);
++}
++
++#define sample_read_group__for_each(v, nr, rf) \
++ for (int __i = 0; __i < (int)nr; v = next_sample_read_value(v, rf), __i++)
++
+ struct ip_callchain {
+ u64 nr;
+ u64 ips[];
+diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
+index 4f4226f380d1c..1a6f42924cca8 100644
+--- a/tools/perf/util/evsel.c
++++ b/tools/perf/util/evsel.c
+@@ -1493,7 +1493,7 @@ static int evsel__read_one(struct evsel *evsel, int cpu, int thread)
+ }
+
+ static void evsel__set_count(struct evsel *counter, int cpu_map_idx, int thread,
+- u64 val, u64 ena, u64 run)
++ u64 val, u64 ena, u64 run, u64 lost)
+ {
+ struct perf_counts_values *count;
+
+@@ -1502,6 +1502,7 @@ static void evsel__set_count(struct evsel *counter, int cpu_map_idx, int thread,
+ count->val = val;
+ count->ena = ena;
+ count->run = run;
++ count->lost = lost;
+
+ perf_counts__set_loaded(counter->counts, cpu_map_idx, thread, true);
+ }
+@@ -1510,7 +1511,7 @@ static int evsel__process_group_data(struct evsel *leader, int cpu_map_idx, int
+ {
+ u64 read_format = leader->core.attr.read_format;
+ struct sample_read_value *v;
+- u64 nr, ena = 0, run = 0, i;
++ u64 nr, ena = 0, run = 0, lost = 0;
+
+ nr = *data++;
+
+@@ -1523,18 +1524,18 @@ static int evsel__process_group_data(struct evsel *leader, int cpu_map_idx, int
+ if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
+ run = *data++;
+
+- v = (struct sample_read_value *) data;
+-
+- evsel__set_count(leader, cpu_map_idx, thread, v[0].value, ena, run);
+-
+- for (i = 1; i < nr; i++) {
++ v = (void *)data;
++ sample_read_group__for_each(v, nr, read_format) {
+ struct evsel *counter;
+
+- counter = evlist__id2evsel(leader->evlist, v[i].id);
++ counter = evlist__id2evsel(leader->evlist, v->id);
+ if (!counter)
+ return -EINVAL;
+
+- evsel__set_count(counter, cpu_map_idx, thread, v[i].value, ena, run);
++ if (read_format & PERF_FORMAT_LOST)
++ lost = v->lost;
++
++ evsel__set_count(counter, cpu_map_idx, thread, v->value, ena, run, lost);
+ }
+
+ return 0;
+@@ -2358,8 +2359,8 @@ int evsel__parse_sample(struct evsel *evsel, union perf_event *event,
+
+ if (data->read.group.nr > max_group_nr)
+ return -EFAULT;
+- sz = data->read.group.nr *
+- sizeof(struct sample_read_value);
++
++ sz = data->read.group.nr * sample_read_value_size(read_format);
+ OVERFLOW_CHECK(array, sz, max_size);
+ data->read.group.values =
+ (struct sample_read_value *)array;
+@@ -2368,6 +2369,12 @@ int evsel__parse_sample(struct evsel *evsel, union perf_event *event,
+ OVERFLOW_CHECK_u64(array);
+ data->read.one.id = *array;
+ array++;
++
++ if (read_format & PERF_FORMAT_LOST) {
++ OVERFLOW_CHECK_u64(array);
++ data->read.one.lost = *array;
++ array++;
++ }
+ }
+ }
+
+diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
+index c0c010350bc2a..ec547bf99182b 100644
+--- a/tools/perf/util/scripting-engines/trace-event-python.c
++++ b/tools/perf/util/scripting-engines/trace-event-python.c
+@@ -622,15 +622,19 @@ static PyObject *python_process_brstacksym(struct perf_sample *sample,
+ return pylist;
+ }
+
+-static PyObject *get_sample_value_as_tuple(struct sample_read_value *value)
++static PyObject *get_sample_value_as_tuple(struct sample_read_value *value,
++ u64 read_format)
+ {
+ PyObject *t;
+
+- t = PyTuple_New(2);
++ t = PyTuple_New(3);
+ if (!t)
+ Py_FatalError("couldn't create Python tuple");
+ PyTuple_SetItem(t, 0, PyLong_FromUnsignedLongLong(value->id));
+ PyTuple_SetItem(t, 1, PyLong_FromUnsignedLongLong(value->value));
++ if (read_format & PERF_FORMAT_LOST)
++ PyTuple_SetItem(t, 2, PyLong_FromUnsignedLongLong(value->lost));
++
+ return t;
+ }
+
+@@ -661,12 +665,17 @@ static void set_sample_read_in_dict(PyObject *dict_sample,
+ Py_FatalError("couldn't create Python list");
+
+ if (read_format & PERF_FORMAT_GROUP) {
+- for (i = 0; i < sample->read.group.nr; i++) {
+- PyObject *t = get_sample_value_as_tuple(&sample->read.group.values[i]);
++ struct sample_read_value *v = sample->read.group.values;
++
++ i = 0;
++ sample_read_group__for_each(v, sample->read.group.nr, read_format) {
++ PyObject *t = get_sample_value_as_tuple(v, read_format);
+ PyList_SET_ITEM(values, i, t);
++ i++;
+ }
+ } else {
+- PyObject *t = get_sample_value_as_tuple(&sample->read.one);
++ PyObject *t = get_sample_value_as_tuple(&sample->read.one,
++ read_format);
+ PyList_SET_ITEM(values, 0, t);
+ }
+ pydict_set_item_string_decref(dict_sample, "values", values);
+diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
+index 562e9b8080272..7ba9dd1402ed2 100644
+--- a/tools/perf/util/session.c
++++ b/tools/perf/util/session.c
+@@ -1254,21 +1254,25 @@ static void sample_read__printf(struct perf_sample *sample, u64 read_format)
+ sample->read.time_running);
+
+ if (read_format & PERF_FORMAT_GROUP) {
+- u64 i;
++ struct sample_read_value *value = sample->read.group.values;
+
+ printf(".... group nr %" PRIu64 "\n", sample->read.group.nr);
+
+- for (i = 0; i < sample->read.group.nr; i++) {
+- struct sample_read_value *value;
+-
+- value = &sample->read.group.values[i];
++ sample_read_group__for_each(value, sample->read.group.nr, read_format) {
+ printf("..... id %016" PRIx64
+- ", value %016" PRIx64 "\n",
++ ", value %016" PRIx64,
+ value->id, value->value);
++ if (read_format & PERF_FORMAT_LOST)
++ printf(", lost %" PRIu64, value->lost);
++ printf("\n");
+ }
+- } else
+- printf("..... id %016" PRIx64 ", value %016" PRIx64 "\n",
++ } else {
++ printf("..... id %016" PRIx64 ", value %016" PRIx64,
+ sample->read.one.id, sample->read.one.value);
++ if (read_format & PERF_FORMAT_LOST)
++ printf(", lost %" PRIu64, sample->read.one.lost);
++ printf("\n");
++ }
+ }
+
+ static void dump_event(struct evlist *evlist, union perf_event *event,
+@@ -1381,6 +1385,9 @@ static void dump_read(struct evsel *evsel, union perf_event *event)
+
+ if (read_format & PERF_FORMAT_ID)
+ printf("... id : %" PRI_lu64 "\n", read_event->id);
++
++ if (read_format & PERF_FORMAT_LOST)
++ printf("... lost : %" PRI_lu64 "\n", read_event->lost);
+ }
+
+ static struct machine *machines__find_for_cpumode(struct machines *machines,
+@@ -1440,14 +1447,14 @@ static int deliver_sample_group(struct evlist *evlist,
+ struct perf_tool *tool,
+ union perf_event *event,
+ struct perf_sample *sample,
+- struct machine *machine)
++ struct machine *machine,
++ u64 read_format)
+ {
+ int ret = -EINVAL;
+- u64 i;
++ struct sample_read_value *v = sample->read.group.values;
+
+- for (i = 0; i < sample->read.group.nr; i++) {
+- ret = deliver_sample_value(evlist, tool, event, sample,
+- &sample->read.group.values[i],
++ sample_read_group__for_each(v, sample->read.group.nr, read_format) {
++ ret = deliver_sample_value(evlist, tool, event, sample, v,
+ machine);
+ if (ret)
+ break;
+@@ -1471,7 +1478,7 @@ static int evlist__deliver_sample(struct evlist *evlist, struct perf_tool *tool,
+ /* For PERF_SAMPLE_READ we have either single or group mode. */
+ if (read_format & PERF_FORMAT_GROUP)
+ return deliver_sample_group(evlist, tool, event, sample,
+- machine);
++ machine, read_format);
+ else
+ return deliver_sample_value(evlist, tool, event, sample,
+ &sample->read.one, machine);
+diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c
+index c69ad7a1a6a78..d020f286b9c1f 100644
+--- a/tools/perf/util/synthetic-events.c
++++ b/tools/perf/util/synthetic-events.c
+@@ -1436,11 +1436,12 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
+ result += sizeof(u64);
+ /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
+ if (read_format & PERF_FORMAT_GROUP) {
+- sz = sample->read.group.nr *
+- sizeof(struct sample_read_value);
+- result += sz;
++ sz = sample_read_value_size(read_format);
++ result += sz * sample->read.group.nr;
+ } else {
+ result += sizeof(u64);
++ if (read_format & PERF_FORMAT_LOST)
++ result += sizeof(u64);
+ }
+ }
+
+@@ -1525,6 +1526,20 @@ void __weak arch_perf_synthesize_sample_weight(const struct perf_sample *data,
+ *array = data->weight;
+ }
+
++static __u64 *copy_read_group_values(__u64 *array, __u64 read_format,
++ const struct perf_sample *sample)
++{
++ size_t sz = sample_read_value_size(read_format);
++ struct sample_read_value *v = sample->read.group.values;
++
++ sample_read_group__for_each(v, sample->read.group.nr, read_format) {
++ /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
++ memcpy(array, v, sz);
++ array = (void *)array + sz;
++ }
++ return array;
++}
++
+ int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format,
+ const struct perf_sample *sample)
+ {
+@@ -1606,13 +1621,16 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_fo
+
+ /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
+ if (read_format & PERF_FORMAT_GROUP) {
+- sz = sample->read.group.nr *
+- sizeof(struct sample_read_value);
+- memcpy(array, sample->read.group.values, sz);
+- array = (void *)array + sz;
++ array = copy_read_group_values(array, read_format,
++ sample);
+ } else {
+ *array = sample->read.one.id;
+ array++;
++
++ if (read_format & PERF_FORMAT_LOST) {
++ *array = sample->read.one.lost;
++ array++;
++ }
+ }
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 9b04144929cce8710785d3ec73d7cbee76d2382f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Aug 2024 14:48:23 +0800
+Subject: pinctrl: mvebu: Fix devinit_dove_pinctrl_probe function
+
+From: Wang Jianzheng <wangjianzheng@vivo.com>
+
+[ Upstream commit c25478419f6fd3f74c324a21ec007cf14f2688d7 ]
+
+When an error occurs during the execution of the function
+__devinit_dove_pinctrl_probe, the clk is not properly disabled.
+
+Fix this by calling clk_disable_unprepare before return.
+
+Fixes: ba607b6238a1 ("pinctrl: mvebu: make pdma clock on dove mandatory")
+Signed-off-by: Wang Jianzheng <wangjianzheng@vivo.com>
+Link: https://lore.kernel.org/20240829064823.19808-1-wangjianzheng@vivo.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mvebu/pinctrl-dove.c | 42 +++++++++++++++++++---------
+ 1 file changed, 29 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/pinctrl/mvebu/pinctrl-dove.c b/drivers/pinctrl/mvebu/pinctrl-dove.c
+index bd74daa9ed666..c84326dfe371c 100644
+--- a/drivers/pinctrl/mvebu/pinctrl-dove.c
++++ b/drivers/pinctrl/mvebu/pinctrl-dove.c
+@@ -769,7 +769,7 @@ static int dove_pinctrl_probe(struct platform_device *pdev)
+ of_match_device(dove_pinctrl_of_match, &pdev->dev);
+ struct mvebu_mpp_ctrl_data *mpp_data;
+ void __iomem *base;
+- int i;
++ int i, ret;
+
+ pdev->dev.platform_data = (void *)match->data;
+
+@@ -785,13 +785,17 @@ static int dove_pinctrl_probe(struct platform_device *pdev)
+ clk_prepare_enable(clk);
+
+ base = devm_platform_get_and_ioremap_resource(pdev, 0, &mpp_res);
+- if (IS_ERR(base))
+- return PTR_ERR(base);
++ if (IS_ERR(base)) {
++ ret = PTR_ERR(base);
++ goto err_probe;
++ }
+
+ mpp_data = devm_kcalloc(&pdev->dev, dove_pinctrl_info.ncontrols,
+ sizeof(*mpp_data), GFP_KERNEL);
+- if (!mpp_data)
+- return -ENOMEM;
++ if (!mpp_data) {
++ ret = -ENOMEM;
++ goto err_probe;
++ }
+
+ dove_pinctrl_info.control_data = mpp_data;
+ for (i = 0; i < ARRAY_SIZE(dove_mpp_controls); i++)
+@@ -810,8 +814,10 @@ static int dove_pinctrl_probe(struct platform_device *pdev)
+ }
+
+ mpp4_base = devm_ioremap_resource(&pdev->dev, res);
+- if (IS_ERR(mpp4_base))
+- return PTR_ERR(mpp4_base);
++ if (IS_ERR(mpp4_base)) {
++ ret = PTR_ERR(mpp4_base);
++ goto err_probe;
++ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ if (!res) {
+@@ -822,8 +828,10 @@ static int dove_pinctrl_probe(struct platform_device *pdev)
+ }
+
+ pmu_base = devm_ioremap_resource(&pdev->dev, res);
+- if (IS_ERR(pmu_base))
+- return PTR_ERR(pmu_base);
++ if (IS_ERR(pmu_base)) {
++ ret = PTR_ERR(pmu_base);
++ goto err_probe;
++ }
+
+ gconfmap = syscon_regmap_lookup_by_compatible("marvell,dove-global-config");
+ if (IS_ERR(gconfmap)) {
+@@ -833,12 +841,17 @@ static int dove_pinctrl_probe(struct platform_device *pdev)
+ adjust_resource(&fb_res,
+ (mpp_res->start & INT_REGS_MASK) + GC_REGS_OFFS, 0x14);
+ gc_base = devm_ioremap_resource(&pdev->dev, &fb_res);
+- if (IS_ERR(gc_base))
+- return PTR_ERR(gc_base);
++ if (IS_ERR(gc_base)) {
++ ret = PTR_ERR(gc_base);
++ goto err_probe;
++ }
++
+ gconfmap = devm_regmap_init_mmio(&pdev->dev,
+ gc_base, &gc_regmap_config);
+- if (IS_ERR(gconfmap))
+- return PTR_ERR(gconfmap);
++ if (IS_ERR(gconfmap)) {
++ ret = PTR_ERR(gconfmap);
++ goto err_probe;
++ }
+ }
+
+ /* Warn on any missing DT resource */
+@@ -846,6 +859,9 @@ static int dove_pinctrl_probe(struct platform_device *pdev)
+ dev_warn(&pdev->dev, FW_BUG "Missing pinctrl regs in DTB. Please update your firmware.\n");
+
+ return mvebu_pinctrl_probe(pdev);
++err_probe:
++ clk_disable_unprepare(clk);
++ return ret;
+ }
+
+ static struct platform_driver dove_pinctrl_driver = {
+--
+2.43.0
+
--- /dev/null
+From e7cff4c077561ed00bd0c9b4f77945da04360850 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Jul 2023 20:47:40 +0800
+Subject: pinctrl: mvebu: Use devm_platform_get_and_ioremap_resource()
+
+From: Yangtao Li <frank.li@vivo.com>
+
+[ Upstream commit 2d357f25663ddfef47ffe26da21155302153d168 ]
+
+Convert platform_get_resource(), devm_ioremap_resource() to a single
+call to devm_platform_get_and_ioremap_resource(), as this is exactly
+what this function does.
+
+Signed-off-by: Yangtao Li <frank.li@vivo.com>
+Link: https://lore.kernel.org/r/20230704124742.9596-2-frank.li@vivo.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Stable-dep-of: c25478419f6f ("pinctrl: mvebu: Fix devinit_dove_pinctrl_probe function")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mvebu/pinctrl-dove.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/pinctrl/mvebu/pinctrl-dove.c b/drivers/pinctrl/mvebu/pinctrl-dove.c
+index 545486d98532d..bd74daa9ed666 100644
+--- a/drivers/pinctrl/mvebu/pinctrl-dove.c
++++ b/drivers/pinctrl/mvebu/pinctrl-dove.c
+@@ -784,8 +784,7 @@ static int dove_pinctrl_probe(struct platform_device *pdev)
+ }
+ clk_prepare_enable(clk);
+
+- mpp_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- base = devm_ioremap_resource(&pdev->dev, mpp_res);
++ base = devm_platform_get_and_ioremap_resource(pdev, 0, &mpp_res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+--
+2.43.0
+
--- /dev/null
+From cba8bdce0e36443695289f7bda8c864f96ba3b03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Aug 2024 10:46:25 +0800
+Subject: pinctrl: single: fix missing error code in pcs_probe()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit cacd8cf79d7823b07619865e994a7916fcc8ae91 ]
+
+If pinctrl_enable() fails in pcs_probe(), it should return the error code.
+
+Fixes: 8f773bfbdd42 ("pinctrl: single: fix possible memory leak when pinctrl_enable() fails")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/20240819024625.154441-1-yangyingliang@huaweicloud.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/pinctrl-single.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
+index d32d5c5e99bcd..28f3fabc72e30 100644
+--- a/drivers/pinctrl/pinctrl-single.c
++++ b/drivers/pinctrl/pinctrl-single.c
+@@ -1919,7 +1919,8 @@ static int pcs_probe(struct platform_device *pdev)
+
+ dev_info(pcs->dev, "%i pins, size %u\n", pcs->desc.npins, pcs->size);
+
+- if (pinctrl_enable(pcs->pctl))
++ ret = pinctrl_enable(pcs->pctl);
++ if (ret)
+ goto free;
+
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From 8cdafec5c46cc40cb7fd23e7d5a7d5fa59c546cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Sep 2024 16:30:45 +0200
+Subject: pmdomain: core: Harden inter-column space in debug summary
+
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+
+[ Upstream commit 692c20c4d075bd452acfbbc68200fc226c7c9496 ]
+
+The inter-column space in the debug summary is two spaces. However, in
+one case, the extra space is handled implicitly in a field width
+specifier. Make inter-column space explicit to ease future maintenance.
+
+Fixes: 45fbc464b047 ("PM: domains: Add "performance" column to debug summary")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/ae61eb363621b981edde878e1e74d701702a579f.1725459707.git.geert+renesas@glider.be
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/power/domain.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
+index aaf6c297c63d2..fda0a5e50a2d9 100644
+--- a/drivers/base/power/domain.c
++++ b/drivers/base/power/domain.c
+@@ -3053,7 +3053,7 @@ static int genpd_summary_one(struct seq_file *s,
+ else
+ snprintf(state, sizeof(state), "%s",
+ status_lookup[genpd->status]);
+- seq_printf(s, "%-30s %-50s %u", genpd->name, state, genpd->performance_state);
++ seq_printf(s, "%-30s %-49s %u", genpd->name, state, genpd->performance_state);
+
+ /*
+ * Modifications on the list require holding locks on both
+--
+2.43.0
+
--- /dev/null
+From 8648c0b5a05e64863aa82056700fe8b2d515bced Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Aug 2024 16:54:43 -0500
+Subject: power: supply: axp20x_battery: Remove design from min and max voltage
+
+From: Chris Morgan <macromorgan@hotmail.com>
+
+[ Upstream commit 61978807b00f8a1817b0e5580981af1cd2f428a5 ]
+
+The POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN and
+POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN values should be immutable
+properties of the battery, but for this driver they are writable values
+and used as the minimum and maximum values for charging. Remove the
+DESIGN designation from these values.
+
+Fixes: 46c202b5f25f ("power: supply: add battery driver for AXP20X and AXP22X PMICs")
+Suggested-by: Chen-Yu Tsai <wens@kernel.org>
+Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20240821215456.962564-3-macroalpha82@gmail.com
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/axp20x_battery.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/power/supply/axp20x_battery.c b/drivers/power/supply/axp20x_battery.c
+index 335e12cc5e2f9..d62a249f65da0 100644
+--- a/drivers/power/supply/axp20x_battery.c
++++ b/drivers/power/supply/axp20x_battery.c
+@@ -304,11 +304,11 @@ static int axp20x_battery_get_prop(struct power_supply *psy,
+ val->intval = reg & AXP209_FG_PERCENT;
+ break;
+
+- case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
++ case POWER_SUPPLY_PROP_VOLTAGE_MAX:
+ return axp20x_batt->data->get_max_voltage(axp20x_batt,
+ &val->intval);
+
+- case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
++ case POWER_SUPPLY_PROP_VOLTAGE_MIN:
+ ret = regmap_read(axp20x_batt->regmap, AXP20X_V_OFF, ®);
+ if (ret)
+ return ret;
+@@ -456,10 +456,10 @@ static int axp20x_battery_set_prop(struct power_supply *psy,
+ struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
+
+ switch (psp) {
+- case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
++ case POWER_SUPPLY_PROP_VOLTAGE_MIN:
+ return axp20x_set_voltage_min_design(axp20x_batt, val->intval);
+
+- case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
++ case POWER_SUPPLY_PROP_VOLTAGE_MAX:
+ return axp20x_batt->data->set_max_voltage(axp20x_batt, val->intval);
+
+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
+@@ -494,8 +494,8 @@ static enum power_supply_property axp20x_battery_props[] = {
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
+ POWER_SUPPLY_PROP_HEALTH,
+- POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+- POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
++ POWER_SUPPLY_PROP_VOLTAGE_MAX,
++ POWER_SUPPLY_PROP_VOLTAGE_MIN,
+ POWER_SUPPLY_PROP_CAPACITY,
+ };
+
+@@ -503,8 +503,8 @@ static int axp20x_battery_prop_writeable(struct power_supply *psy,
+ enum power_supply_property psp)
+ {
+ return psp == POWER_SUPPLY_PROP_STATUS ||
+- psp == POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN ||
+- psp == POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN ||
++ psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
++ psp == POWER_SUPPLY_PROP_VOLTAGE_MAX ||
+ psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT ||
+ psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX;
+ }
+--
+2.43.0
+
--- /dev/null
+From 46f883df10db85028a8ae6ffd86bcb87e562e047 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Aug 2024 12:51:14 +0200
+Subject: power: supply: max17042_battery: Fix SOC threshold calc w/ no current
+ sense
+
+From: Artur Weber <aweber.kernel@gmail.com>
+
+[ Upstream commit 3a3acf839b2cedf092bdd1ff65b0e9895df1656b ]
+
+Commit 223a3b82834f ("power: supply: max17042_battery: use VFSOC for
+capacity when no rsns") made it so that capacity on systems without
+current sensing would be read from VFSOC instead of RepSOC. However,
+the SOC threshold calculation still read RepSOC to get the SOC
+regardless of the current sensing option state.
+
+Fix this by applying the same conditional to determine which register
+should be read.
+
+This also seems to be the intended behavior as per the datasheet - SOC
+alert config value in MiscCFG on setups without current sensing is set
+to a value of 0b11, indicating SOC alerts being generated based on
+VFSOC, instead of 0b00 which indicates SOC alerts being generated based
+on RepSOC.
+
+This fixes an issue on the Galaxy S3/Midas boards, where the alert
+interrupt would be constantly retriggered, causing high CPU usage
+on idle (around ~12%-15%).
+
+Fixes: e5f3872d2044 ("max17042: Add support for signalling change in SOC")
+Signed-off-by: Artur Weber <aweber.kernel@gmail.com>
+Reviewed-by: Henrik Grimler <henrik@grimler.se>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20240817-max17042-soc-threshold-fix-v1-1-72b45899c3cc@gmail.com
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/max17042_battery.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/power/supply/max17042_battery.c b/drivers/power/supply/max17042_battery.c
+index aaf6f1bd3d298..754d78b4c0aad 100644
+--- a/drivers/power/supply/max17042_battery.c
++++ b/drivers/power/supply/max17042_battery.c
+@@ -857,7 +857,10 @@ static void max17042_set_soc_threshold(struct max17042_chip *chip, u16 off)
+ /* program interrupt thresholds such that we should
+ * get interrupt for every 'off' perc change in the soc
+ */
+- regmap_read(map, MAX17042_RepSOC, &soc);
++ if (chip->pdata->enable_current_sense)
++ regmap_read(map, MAX17042_RepSOC, &soc);
++ else
++ regmap_read(map, MAX17042_VFSOC, &soc);
+ soc >>= 8;
+ soc_tr = (soc + off) << 8;
+ if (off < soc)
+--
+2.43.0
+
--- /dev/null
+From 3076184eae4c674b945867376083d7279b9e2f81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jun 2022 12:32:24 +0200
+Subject: powerpc/32: Remove 'noltlbs' kernel parameter
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 56e54b4e6c477b2a7df43f9a320ae5f9a5bfb16c ]
+
+Mapping without large TLBs has no added value on the 8xx.
+
+Mapping without large TLBs is still necessary on 40x when
+selecting CONFIG_KFENCE or CONFIG_DEBUG_PAGEALLOC or
+CONFIG_STRICT_KERNEL_RWX, but this is done automatically
+and doesn't require user selection.
+
+Remove 'noltlbs' kernel parameter, the user has no reason
+to use it.
+
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/80ca17bd39cf608a8ebd0764d7064a498e131199.1655202721.git.christophe.leroy@csgroup.eu
+Stable-dep-of: f9f2bff64c2f ("powerpc/8xx: Fix initial memory mapping")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/admin-guide/kernel-parameters.txt | 3 ---
+ arch/powerpc/mm/init_32.c | 3 ---
+ arch/powerpc/mm/nohash/8xx.c | 9 ---------
+ 3 files changed, 15 deletions(-)
+
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
+index e2c2ccba6e388..c22a8ee02e73b 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -3626,9 +3626,6 @@
+
+ nolapic_timer [X86-32,APIC] Do not use the local APIC timer.
+
+- noltlbs [PPC] Do not use large page/tlb entries for kernel
+- lowmem mapping on PPC40x and PPC8xx
+-
+ nomca [IA-64] Disable machine check abort handling
+
+ nomce [X86-32] Disable Machine Check Exception
+diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
+index b702f2b642957..967432d1b6c78 100644
+--- a/arch/powerpc/mm/init_32.c
++++ b/arch/powerpc/mm/init_32.c
+@@ -80,9 +80,6 @@ unsigned long __max_low_memory = MAX_LOW_MEM;
+ */
+ static void __init MMU_setup(void)
+ {
+- if (strstr(boot_command_line, "noltlbs")) {
+- __map_without_ltlbs = 1;
+- }
+ if (IS_ENABLED(CONFIG_PPC_8xx))
+ return;
+
+diff --git a/arch/powerpc/mm/nohash/8xx.c b/arch/powerpc/mm/nohash/8xx.c
+index 5348e1f9eb940..94efd4fa6e768 100644
+--- a/arch/powerpc/mm/nohash/8xx.c
++++ b/arch/powerpc/mm/nohash/8xx.c
+@@ -18,8 +18,6 @@
+
+ #define IMMR_SIZE (FIX_IMMR_SIZE << PAGE_SHIFT)
+
+-extern int __map_without_ltlbs;
+-
+ static unsigned long block_mapped_ram;
+
+ /*
+@@ -32,8 +30,6 @@ phys_addr_t v_block_mapped(unsigned long va)
+
+ if (va >= VIRT_IMMR_BASE && va < VIRT_IMMR_BASE + IMMR_SIZE)
+ return p + va - VIRT_IMMR_BASE;
+- if (__map_without_ltlbs)
+- return 0;
+ if (va >= PAGE_OFFSET && va < PAGE_OFFSET + block_mapped_ram)
+ return __pa(va);
+ return 0;
+@@ -49,8 +45,6 @@ unsigned long p_block_mapped(phys_addr_t pa)
+
+ if (pa >= p && pa < p + IMMR_SIZE)
+ return VIRT_IMMR_BASE + pa - p;
+- if (__map_without_ltlbs)
+- return 0;
+ if (pa < block_mapped_ram)
+ return (unsigned long)__va(pa);
+ return 0;
+@@ -157,9 +151,6 @@ unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
+
+ mmu_mapin_immr();
+
+- if (__map_without_ltlbs)
+- return 0;
+-
+ mmu_mapin_ram_chunk(0, boundary, PAGE_KERNEL_TEXT, true);
+ if (debug_pagealloc_enabled_or_kfence()) {
+ top = boundary;
+--
+2.43.0
+
--- /dev/null
+From b97c025eefe95ed9a35564b7207aa54bb7847742 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Jun 2022 12:32:23 +0200
+Subject: powerpc/32: Remove the 'nobats' kernel parameter
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 1ce844973bb516e95d3f2bcb001a3992548def9d ]
+
+Mapping without BATs doesn't bring any added value to the user.
+
+Remove that option.
+
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/6977314c823cfb728bc0273cea634b41807bfb64.1655202721.git.christophe.leroy@csgroup.eu
+Stable-dep-of: f9f2bff64c2f ("powerpc/8xx: Fix initial memory mapping")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/admin-guide/kernel-parameters.txt | 3 ---
+ arch/powerpc/mm/book3s32/mmu.c | 2 +-
+ arch/powerpc/mm/init_32.c | 11 -----------
+ arch/powerpc/mm/mmu_decl.h | 1 -
+ arch/powerpc/platforms/83xx/misc.c | 14 ++++++--------
+ 5 files changed, 7 insertions(+), 24 deletions(-)
+
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
+index cf35b2cf90c27..e2c2ccba6e388 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -3451,9 +3451,6 @@
+
+ noautogroup Disable scheduler automatic task group creation.
+
+- nobats [PPC] Do not use BATs for mapping kernel lowmem
+- on "Classic" PPC cores.
+-
+ nocache [ARM]
+
+ noclflush [BUGS=X86] Don't use the CLFLUSH instruction
+diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c
+index 692c336e4f55b..75c7f35666642 100644
+--- a/arch/powerpc/mm/book3s32/mmu.c
++++ b/arch/powerpc/mm/book3s32/mmu.c
+@@ -165,7 +165,7 @@ unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
+ size = roundup_pow_of_two((unsigned long)_einittext - PAGE_OFFSET);
+ setibat(0, PAGE_OFFSET, 0, size, PAGE_KERNEL_X);
+
+- if (debug_pagealloc_enabled_or_kfence() || __map_without_bats) {
++ if (debug_pagealloc_enabled_or_kfence()) {
+ pr_debug_once("Read-Write memory mapped without BATs\n");
+ if (base >= border)
+ return base;
+diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
+index 3d690be48e845..b702f2b642957 100644
+--- a/arch/powerpc/mm/init_32.c
++++ b/arch/powerpc/mm/init_32.c
+@@ -70,12 +70,6 @@ EXPORT_SYMBOL(agp_special_page);
+
+ void MMU_init(void);
+
+-/*
+- * this tells the system to map all of ram with the segregs
+- * (i.e. page tables) instead of the bats.
+- * -- Cort
+- */
+-int __map_without_bats;
+ int __map_without_ltlbs;
+
+ /* max amount of low RAM to map in */
+@@ -86,11 +80,6 @@ unsigned long __max_low_memory = MAX_LOW_MEM;
+ */
+ static void __init MMU_setup(void)
+ {
+- /* Check for nobats option (used in mapin_ram). */
+- if (strstr(boot_command_line, "nobats")) {
+- __map_without_bats = 1;
+- }
+-
+ if (strstr(boot_command_line, "noltlbs")) {
+ __map_without_ltlbs = 1;
+ }
+diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
+index 21996b9e0a64f..990dccf45fc13 100644
+--- a/arch/powerpc/mm/mmu_decl.h
++++ b/arch/powerpc/mm/mmu_decl.h
+@@ -92,7 +92,6 @@ extern void mapin_ram(void);
+ extern void setbat(int index, unsigned long virt, phys_addr_t phys,
+ unsigned int size, pgprot_t prot);
+
+-extern int __map_without_bats;
+ extern unsigned int rtas_data, rtas_size;
+
+ struct hash_pte;
+diff --git a/arch/powerpc/platforms/83xx/misc.c b/arch/powerpc/platforms/83xx/misc.c
+index 3285dabcf923b..2fb2a85d131fd 100644
+--- a/arch/powerpc/platforms/83xx/misc.c
++++ b/arch/powerpc/platforms/83xx/misc.c
+@@ -121,17 +121,15 @@ void __init mpc83xx_setup_pci(void)
+
+ void __init mpc83xx_setup_arch(void)
+ {
++ phys_addr_t immrbase = get_immrbase();
++ int immrsize = IS_ALIGNED(immrbase, SZ_2M) ? SZ_2M : SZ_1M;
++ unsigned long va = fix_to_virt(FIX_IMMR_BASE);
++
+ if (ppc_md.progress)
+ ppc_md.progress("mpc83xx_setup_arch()", 0);
+
+- if (!__map_without_bats) {
+- phys_addr_t immrbase = get_immrbase();
+- int immrsize = IS_ALIGNED(immrbase, SZ_2M) ? SZ_2M : SZ_1M;
+- unsigned long va = fix_to_virt(FIX_IMMR_BASE);
+-
+- setbat(-1, va, immrbase, immrsize, PAGE_KERNEL_NCG);
+- update_bats();
+- }
++ setbat(-1, va, immrbase, immrsize, PAGE_KERNEL_NCG);
++ update_bats();
+ }
+
+ int machine_check_83xx(struct pt_regs *regs)
+--
+2.43.0
+
--- /dev/null
+From fb9cfc5f221349e796cf627b99a75a319bb9e01c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Aug 2024 19:23:45 +0200
+Subject: powerpc/8xx: Fix initial memory mapping
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit f9f2bff64c2f0dbee57be3d8c2741357ad3d05e6 ]
+
+Commit cf209951fa7f ("powerpc/8xx: Map linear memory with huge pages")
+introduced an initial mapping of kernel TEXT using PAGE_KERNEL_TEXT,
+but the pages that contain kernel TEXT may also contain kernel RODATA,
+and depending on selected debug options PAGE_KERNEL_TEXT may be either
+RWX or ROX. RODATA must be writable during init because it also
+contains ro_after_init data.
+
+So use PAGE_KERNEL_X instead to be sure it is RWX.
+
+Fixes: cf209951fa7f ("powerpc/8xx: Map linear memory with huge pages")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/dac7a828d8497c4548c91840575a706657baa4f1.1724173828.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/mm/nohash/8xx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/mm/nohash/8xx.c b/arch/powerpc/mm/nohash/8xx.c
+index 94efd4fa6e768..3876d1710185d 100644
+--- a/arch/powerpc/mm/nohash/8xx.c
++++ b/arch/powerpc/mm/nohash/8xx.c
+@@ -151,11 +151,11 @@ unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
+
+ mmu_mapin_immr();
+
+- mmu_mapin_ram_chunk(0, boundary, PAGE_KERNEL_TEXT, true);
++ mmu_mapin_ram_chunk(0, boundary, PAGE_KERNEL_X, true);
+ if (debug_pagealloc_enabled_or_kfence()) {
+ top = boundary;
+ } else {
+- mmu_mapin_ram_chunk(boundary, einittext8, PAGE_KERNEL_TEXT, true);
++ mmu_mapin_ram_chunk(boundary, einittext8, PAGE_KERNEL_X, true);
+ mmu_mapin_ram_chunk(einittext8, top, PAGE_KERNEL, true);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 81ecf86784870a012c628df7e88824618230e628 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Aug 2024 19:23:46 +0200
+Subject: powerpc/8xx: Fix kernel vs user address comparison
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 65a82e117ffeeab0baf6f871a1cab11a28ace183 ]
+
+Since commit 9132a2e82adc ("powerpc/8xx: Define a MODULE area below
+kernel text"), module exec space is below PAGE_OFFSET so not only
+space above PAGE_OFFSET, but space above TASK_SIZE need to be seen
+as kernel space.
+
+Until now the problem went undetected because by default TASK_SIZE
+is 0x8000000 which means address space is determined by just
+checking upper address bit. But when TASK_SIZE is over 0x80000000,
+PAGE_OFFSET is used for comparison, leading to thinking module
+addresses are part of user space.
+
+Fix it by using TASK_SIZE instead of PAGE_OFFSET for address
+comparison.
+
+Fixes: 9132a2e82adc ("powerpc/8xx: Define a MODULE area below kernel text")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/3f574c9845ff0a023b46cb4f38d2c45aecd769bd.1724173828.git.christophe.leroy@csgroup.eu
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/head_8xx.S | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
+index 0d073b9fd52c5..4e409eee42b10 100644
+--- a/arch/powerpc/kernel/head_8xx.S
++++ b/arch/powerpc/kernel/head_8xx.S
+@@ -40,12 +40,12 @@
+ #include "head_32.h"
+
+ .macro compare_to_kernel_boundary scratch, addr
+-#if CONFIG_TASK_SIZE <= 0x80000000 && CONFIG_PAGE_OFFSET >= 0x80000000
++#if CONFIG_TASK_SIZE <= 0x80000000 && MODULES_VADDR >= 0x80000000
+ /* By simply checking Address >= 0x80000000, we know if its a kernel address */
+ not. \scratch, \addr
+ #else
+ rlwinm \scratch, \addr, 16, 0xfff8
+- cmpli cr0, \scratch, PAGE_OFFSET@h
++ cmpli cr0, \scratch, TASK_SIZE@h
+ #endif
+ .endm
+
+@@ -403,7 +403,7 @@ FixupDAR:/* Entry point for dcbx workaround. */
+ mfspr r10, SPRN_SRR0
+ mtspr SPRN_MD_EPN, r10
+ rlwinm r11, r10, 16, 0xfff8
+- cmpli cr1, r11, PAGE_OFFSET@h
++ cmpli cr1, r11, TASK_SIZE@h
+ mfspr r11, SPRN_M_TWB /* Get level 1 table */
+ blt+ cr1, 3f
+
+--
+2.43.0
+
--- /dev/null
+From 01ba97cd87dc7dd0f05da282b425b7d62935ab63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Sep 2024 15:51:11 +0200
+Subject: r8169: disable ALDPS per default for RTL8125
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+[ Upstream commit b9c7ac4fe22c608acf6153a3329df2b6b6cd416c ]
+
+En-Wei reported that traffic breaks if cable is unplugged for more
+than 3s and then re-plugged. This was supposed to be fixed by
+621735f59064 ("r8169: fix rare issue with broken rx after link-down on
+RTL8125"). But apparently this didn't fix the issue for everybody.
+The 3s threshold rang a bell, as this is the delay after which ALDPS
+kicks in. And indeed disabling ALDPS fixes the issue for this user.
+Maybe this fixes the issue in general. In a follow-up step we could
+remove the first fix attempt and see whether anybody complains.
+
+Fixes: f1bce4ad2f1c ("r8169: add support for RTL8125")
+Tested-by: En-Wei WU <en-wei.wu@canonical.com>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://patch.msgid.link/778b9d86-05c4-4856-be59-cde4487b9e52@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_phy_config.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/realtek/r8169_phy_config.c b/drivers/net/ethernet/realtek/r8169_phy_config.c
+index a84fd859aec9b..f0a808e164249 100644
+--- a/drivers/net/ethernet/realtek/r8169_phy_config.c
++++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
+@@ -1263,6 +1263,7 @@ static void rtl8125a_2_hw_phy_config(struct rtl8169_private *tp,
+ phy_modify_paged(phydev, 0xa86, 0x15, 0x0001, 0x0000);
+ rtl8168g_enable_gphy_10m(phydev);
+
++ rtl8168g_disable_aldps(phydev);
+ rtl8125a_config_eee_phy(phydev);
+ }
+
+@@ -1302,6 +1303,7 @@ static void rtl8125b_hw_phy_config(struct rtl8169_private *tp,
+ phy_modify_paged(phydev, 0xbf8, 0x12, 0xe000, 0xa000);
+
+ rtl8125_legacy_force_mode(phydev);
++ rtl8168g_disable_aldps(phydev);
+ rtl8125b_config_eee_phy(phydev);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From fa3fd229726f1c4f08bce5d16aea47751aa974ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Sep 2024 10:58:39 -0400
+Subject: RDMA/cxgb4: Added NULL check for lookup_atid
+
+From: Mikhail Lobanov <m.lobanov@rosalinux.ru>
+
+[ Upstream commit e766e6a92410ca269161de059fff0843b8ddd65f ]
+
+The lookup_atid() function can return NULL if the ATID is
+invalid or does not exist in the identifier table, which
+could lead to dereferencing a null pointer without a
+check in the `act_establish()` and `act_open_rpl()` functions.
+Add a NULL check to prevent null pointer dereferencing.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: cfdda9d76436 ("RDMA/cxgb4: Add driver for Chelsio T4 RNIC")
+Signed-off-by: Mikhail Lobanov <m.lobanov@rosalinux.ru>
+Link: https://patch.msgid.link/20240912145844.77516-1-m.lobanov@rosalinux.ru
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/cxgb4/cm.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
+index f159cbb6bb3ea..e6343c89c892e 100644
+--- a/drivers/infiniband/hw/cxgb4/cm.c
++++ b/drivers/infiniband/hw/cxgb4/cm.c
+@@ -1222,6 +1222,8 @@ static int act_establish(struct c4iw_dev *dev, struct sk_buff *skb)
+ int ret;
+
+ ep = lookup_atid(t, atid);
++ if (!ep)
++ return -EINVAL;
+
+ pr_debug("ep %p tid %u snd_isn %u rcv_isn %u\n", ep, tid,
+ be32_to_cpu(req->snd_isn), be32_to_cpu(req->rcv_isn));
+@@ -2279,6 +2281,9 @@ static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
+ int ret = 0;
+
+ ep = lookup_atid(t, atid);
++ if (!ep)
++ return -EINVAL;
++
+ la = (struct sockaddr_in *)&ep->com.local_addr;
+ ra = (struct sockaddr_in *)&ep->com.remote_addr;
+ la6 = (struct sockaddr_in6 *)&ep->com.local_addr;
+--
+2.43.0
+
--- /dev/null
+From 39da4b833bf73aa703957e7c575517f2c9717b49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Sep 2024 17:34:36 +0800
+Subject: RDMA/hns: Don't modify rq next block addr in HIP09 QPC
+
+From: Junxian Huang <huangjunxian6@hisilicon.com>
+
+[ Upstream commit 6928d264e328e0cb5ee7663003a6e46e4cba0a7e ]
+
+The field 'rq next block addr' in QPC can be updated by driver only
+on HIP08. On HIP09 HW updates this field while driver is not allowed.
+
+Fixes: 926a01dc000d ("RDMA/hns: Add QP operations support for hip08 SoC")
+Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Link: https://patch.msgid.link/20240906093444.3571619-2-huangjunxian6@hisilicon.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 3cd65bcca2240..7aaf7d5be91b0 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -4228,12 +4228,14 @@ static int config_qp_rq_buf(struct hns_roce_dev *hr_dev,
+ upper_32_bits(to_hr_hw_page_addr(mtts[0])));
+ hr_reg_clear(qpc_mask, QPC_RQ_CUR_BLK_ADDR_H);
+
+- context->rq_nxt_blk_addr = cpu_to_le32(to_hr_hw_page_addr(mtts[1]));
+- qpc_mask->rq_nxt_blk_addr = 0;
+-
+- hr_reg_write(context, QPC_RQ_NXT_BLK_ADDR_H,
+- upper_32_bits(to_hr_hw_page_addr(mtts[1])));
+- hr_reg_clear(qpc_mask, QPC_RQ_NXT_BLK_ADDR_H);
++ if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08) {
++ context->rq_nxt_blk_addr =
++ cpu_to_le32(to_hr_hw_page_addr(mtts[1]));
++ qpc_mask->rq_nxt_blk_addr = 0;
++ hr_reg_write(context, QPC_RQ_NXT_BLK_ADDR_H,
++ upper_32_bits(to_hr_hw_page_addr(mtts[1])));
++ hr_reg_clear(qpc_mask, QPC_RQ_NXT_BLK_ADDR_H);
++ }
+
+ return 0;
+ }
+--
+2.43.0
+
--- /dev/null
+From b59cdbfb2581ee98f3a5756b7a61625be0a6d9b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Sep 2024 17:34:40 +0800
+Subject: RDMA/hns: Fix spin_unlock_irqrestore() called with IRQs enabled
+
+From: Chengchang Tang <tangchengchang@huawei.com>
+
+[ Upstream commit 74d315b5af180220d561684d15897730135733a6 ]
+
+Fix missuse of spin_lock_irq()/spin_unlock_irq() when
+spin_lock_irqsave()/spin_lock_irqrestore() was hold.
+
+This was discovered through the lock debugging, and the corresponding
+log is as follows:
+
+raw_local_irq_restore() called with IRQs enabled
+WARNING: CPU: 96 PID: 2074 at kernel/locking/irqflag-debug.c:10 warn_bogus_irq_restore+0x30/0x40
+...
+Call trace:
+ warn_bogus_irq_restore+0x30/0x40
+ _raw_spin_unlock_irqrestore+0x84/0xc8
+ add_qp_to_list+0x11c/0x148 [hns_roce_hw_v2]
+ hns_roce_create_qp_common.constprop.0+0x240/0x780 [hns_roce_hw_v2]
+ hns_roce_create_qp+0x98/0x160 [hns_roce_hw_v2]
+ create_qp+0x138/0x258
+ ib_create_qp_kernel+0x50/0xe8
+ create_mad_qp+0xa8/0x128
+ ib_mad_port_open+0x218/0x448
+ ib_mad_init_device+0x70/0x1f8
+ add_client_context+0xfc/0x220
+ enable_device_and_get+0xd0/0x140
+ ib_register_device.part.0+0xf4/0x1c8
+ ib_register_device+0x34/0x50
+ hns_roce_register_device+0x174/0x3d0 [hns_roce_hw_v2]
+ hns_roce_init+0xfc/0x2c0 [hns_roce_hw_v2]
+ __hns_roce_hw_v2_init_instance+0x7c/0x1d0 [hns_roce_hw_v2]
+ hns_roce_hw_v2_init_instance+0x9c/0x180 [hns_roce_hw_v2]
+
+Fixes: 9a4435375cd1 ("IB/hns: Add driver files for hns RoCE driver")
+Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
+Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Link: https://patch.msgid.link/20240906093444.3571619-6-huangjunxian6@hisilicon.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_qp.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c
+index d085998b19c87..ff019e32c4552 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_qp.c
++++ b/drivers/infiniband/hw/hns/hns_roce_qp.c
+@@ -1362,19 +1362,19 @@ void hns_roce_lock_cqs(struct hns_roce_cq *send_cq, struct hns_roce_cq *recv_cq)
+ __acquire(&send_cq->lock);
+ __acquire(&recv_cq->lock);
+ } else if (unlikely(send_cq != NULL && recv_cq == NULL)) {
+- spin_lock_irq(&send_cq->lock);
++ spin_lock(&send_cq->lock);
+ __acquire(&recv_cq->lock);
+ } else if (unlikely(send_cq == NULL && recv_cq != NULL)) {
+- spin_lock_irq(&recv_cq->lock);
++ spin_lock(&recv_cq->lock);
+ __acquire(&send_cq->lock);
+ } else if (send_cq == recv_cq) {
+- spin_lock_irq(&send_cq->lock);
++ spin_lock(&send_cq->lock);
+ __acquire(&recv_cq->lock);
+ } else if (send_cq->cqn < recv_cq->cqn) {
+- spin_lock_irq(&send_cq->lock);
++ spin_lock(&send_cq->lock);
+ spin_lock_nested(&recv_cq->lock, SINGLE_DEPTH_NESTING);
+ } else {
+- spin_lock_irq(&recv_cq->lock);
++ spin_lock(&recv_cq->lock);
+ spin_lock_nested(&send_cq->lock, SINGLE_DEPTH_NESTING);
+ }
+ }
+@@ -1394,13 +1394,13 @@ void hns_roce_unlock_cqs(struct hns_roce_cq *send_cq,
+ spin_unlock(&recv_cq->lock);
+ } else if (send_cq == recv_cq) {
+ __release(&recv_cq->lock);
+- spin_unlock_irq(&send_cq->lock);
++ spin_unlock(&send_cq->lock);
+ } else if (send_cq->cqn < recv_cq->cqn) {
+ spin_unlock(&recv_cq->lock);
+- spin_unlock_irq(&send_cq->lock);
++ spin_unlock(&send_cq->lock);
+ } else {
+ spin_unlock(&send_cq->lock);
+- spin_unlock_irq(&recv_cq->lock);
++ spin_unlock(&recv_cq->lock);
+ }
+ }
+
+--
+2.43.0
+
--- /dev/null
+From bf80dd763ac4d2a4df9e55c5560203b0a7d4fcbf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Sep 2024 17:34:39 +0800
+Subject: RDMA/hns: Fix the overflow risk of hem_list_calc_ba_range()
+
+From: wenglianfa <wenglianfa@huawei.com>
+
+[ Upstream commit d586628b169d14bbf36be64d2b3ec9d9d2fe0432 ]
+
+The max value of 'unit' and 'hop_num' is 2^24 and 2, so the value of
+'step' may exceed the range of u32. Change the type of 'step' to u64.
+
+Fixes: 38389eaa4db1 ("RDMA/hns: Add mtr support for mixed multihop addressing")
+Signed-off-by: wenglianfa <wenglianfa@huawei.com>
+Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Link: https://patch.msgid.link/20240906093444.3571619-5-huangjunxian6@hisilicon.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hem.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c
+index 267474070f271..5f2b434541a2d 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hem.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hem.c
+@@ -1089,9 +1089,9 @@ static bool hem_list_is_bottom_bt(int hopnum, int bt_level)
+ * @bt_level: base address table level
+ * @unit: ba entries per bt page
+ */
+-static u32 hem_list_calc_ba_range(int hopnum, int bt_level, int unit)
++static u64 hem_list_calc_ba_range(int hopnum, int bt_level, int unit)
+ {
+- u32 step;
++ u64 step;
+ int max;
+ int i;
+
+@@ -1127,7 +1127,7 @@ int hns_roce_hem_list_calc_root_ba(const struct hns_roce_buf_region *regions,
+ {
+ struct hns_roce_buf_region *r;
+ int total = 0;
+- int step;
++ u64 step;
+ int i;
+
+ for (i = 0; i < region_cnt; i++) {
+@@ -1158,7 +1158,7 @@ static int hem_list_alloc_mid_bt(struct hns_roce_dev *hr_dev,
+ int ret = 0;
+ int max_ofs;
+ int level;
+- u32 step;
++ u64 step;
+ int end;
+
+ if (hopnum <= 1)
+@@ -1195,7 +1195,7 @@ static int hem_list_alloc_mid_bt(struct hns_roce_dev *hr_dev,
+ }
+
+ start_aligned = (distance / step) * step + r->offset;
+- end = min_t(int, start_aligned + step - 1, max_ofs);
++ end = min_t(u64, start_aligned + step - 1, max_ofs);
+ cur = hem_list_alloc_item(hr_dev, start_aligned, end, unit,
+ true, level);
+ if (!cur) {
+@@ -1284,7 +1284,7 @@ static int setup_middle_bt(struct hns_roce_dev *hr_dev, void *cpu_base,
+ struct hns_roce_hem_item *hem, *temp_hem;
+ int total = 0;
+ int offset;
+- int step;
++ u64 step;
+
+ step = hem_list_calc_ba_range(r->hopnum, 1, unit);
+ if (step < 1)
+--
+2.43.0
+
--- /dev/null
+From 37e14c302ea1038ffc929ab067291b3bff635ccb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 21:43:50 +0800
+Subject: RDMA/hns: Fix the wrong type of return value of the interrupt handler
+
+From: Haoyue Xu <xuhaoyue1@hisilicon.com>
+
+[ Upstream commit d95e0a0c6c9602ff6bb90c1c20987b204493d8e1 ]
+
+The type of return value of the interrupt handler should be irqreturn_t.
+
+Link: https://lore.kernel.org/r/20220714134353.16700-3-liangwenpeng@huawei.com
+Signed-off-by: Haoyue Xu <xuhaoyue1@hisilicon.com>
+Signed-off-by: Wenpeng Liang <liangwenpeng@huawei.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: 4321feefa550 ("RDMA/hns: Fix VF triggering PF reset in abnormal interrupt handler")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 27 +++++++++++-----------
+ 1 file changed, 14 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 71ba2960e4b0f..4c98341602067 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -5674,12 +5674,12 @@ static struct hns_roce_aeqe *next_aeqe_sw_v2(struct hns_roce_eq *eq)
+ !!(eq->cons_index & eq->entries)) ? aeqe : NULL;
+ }
+
+-static int hns_roce_v2_aeq_int(struct hns_roce_dev *hr_dev,
+- struct hns_roce_eq *eq)
++static irqreturn_t hns_roce_v2_aeq_int(struct hns_roce_dev *hr_dev,
++ struct hns_roce_eq *eq)
+ {
+ struct device *dev = hr_dev->dev;
+ struct hns_roce_aeqe *aeqe = next_aeqe_sw_v2(eq);
+- int aeqe_found = 0;
++ irqreturn_t aeqe_found = IRQ_NONE;
+ int event_type;
+ u32 queue_num;
+ int sub_type;
+@@ -5739,7 +5739,7 @@ static int hns_roce_v2_aeq_int(struct hns_roce_dev *hr_dev,
+ eq->event_type = event_type;
+ eq->sub_type = sub_type;
+ ++eq->cons_index;
+- aeqe_found = 1;
++ aeqe_found = IRQ_HANDLED;
+
+ hns_roce_v2_init_irq_work(hr_dev, eq, queue_num);
+
+@@ -5747,7 +5747,8 @@ static int hns_roce_v2_aeq_int(struct hns_roce_dev *hr_dev,
+ }
+
+ update_eq_db(eq);
+- return aeqe_found;
++
++ return IRQ_RETVAL(aeqe_found);
+ }
+
+ static struct hns_roce_ceqe *next_ceqe_sw_v2(struct hns_roce_eq *eq)
+@@ -5762,11 +5763,11 @@ static struct hns_roce_ceqe *next_ceqe_sw_v2(struct hns_roce_eq *eq)
+ (!!(eq->cons_index & eq->entries)) ? ceqe : NULL;
+ }
+
+-static int hns_roce_v2_ceq_int(struct hns_roce_dev *hr_dev,
+- struct hns_roce_eq *eq)
++static irqreturn_t hns_roce_v2_ceq_int(struct hns_roce_dev *hr_dev,
++ struct hns_roce_eq *eq)
+ {
+ struct hns_roce_ceqe *ceqe = next_ceqe_sw_v2(eq);
+- int ceqe_found = 0;
++ irqreturn_t ceqe_found = IRQ_NONE;
+ u32 cqn;
+
+ while (ceqe) {
+@@ -5781,21 +5782,21 @@ static int hns_roce_v2_ceq_int(struct hns_roce_dev *hr_dev,
+ hns_roce_cq_completion(hr_dev, cqn);
+
+ ++eq->cons_index;
+- ceqe_found = 1;
++ ceqe_found = IRQ_HANDLED;
+
+ ceqe = next_ceqe_sw_v2(eq);
+ }
+
+ update_eq_db(eq);
+
+- return ceqe_found;
++ return IRQ_RETVAL(ceqe_found);
+ }
+
+ static irqreturn_t hns_roce_v2_msix_interrupt_eq(int irq, void *eq_ptr)
+ {
+ struct hns_roce_eq *eq = eq_ptr;
+ struct hns_roce_dev *hr_dev = eq->hr_dev;
+- int int_work;
++ irqreturn_t int_work;
+
+ if (eq->type_flag == HNS_ROCE_CEQ)
+ /* Completion event interrupt */
+@@ -5811,7 +5812,7 @@ static irqreturn_t hns_roce_v2_msix_interrupt_abn(int irq, void *dev_id)
+ {
+ struct hns_roce_dev *hr_dev = dev_id;
+ struct device *dev = hr_dev->dev;
+- int int_work = 0;
++ irqreturn_t int_work = IRQ_NONE;
+ u32 int_st;
+ u32 int_en;
+
+@@ -5839,7 +5840,7 @@ static irqreturn_t hns_roce_v2_msix_interrupt_abn(int irq, void *dev_id)
+ int_en |= 1 << HNS_ROCE_V2_VF_ABN_INT_EN_S;
+ roce_write(hr_dev, ROCEE_VF_ABN_INT_EN_REG, int_en);
+
+- int_work = 1;
++ int_work = IRQ_HANDLED;
+ } else {
+ dev_err(dev, "There is no abnormal irq found!\n");
+ }
+--
+2.43.0
+
--- /dev/null
+From 0b2da7c6262693517a5cd0e852541e5cf83f0554 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Sep 2024 17:34:41 +0800
+Subject: RDMA/hns: Fix VF triggering PF reset in abnormal interrupt handler
+
+From: Junxian Huang <huangjunxian6@hisilicon.com>
+
+[ Upstream commit 4321feefa5501a746ebf6a7d8b59e6b955ae1860 ]
+
+In abnormal interrupt handler, a PF reset will be triggered even if
+the device is a VF. It should be a VF reset.
+
+Fixes: 2b9acb9a97fe ("RDMA/hns: Add the process of AEQ overflow for hip08")
+Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Link: https://patch.msgid.link/20240906093444.3571619-7-huangjunxian6@hisilicon.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 92cff8d014cbe..64d458fd39ba9 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -5814,6 +5814,7 @@ static irqreturn_t abnormal_interrupt_basic(struct hns_roce_dev *hr_dev,
+ struct pci_dev *pdev = hr_dev->pci_dev;
+ struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);
+ const struct hnae3_ae_ops *ops = ae_dev->ops;
++ enum hnae3_reset_type reset_type;
+ irqreturn_t int_work = IRQ_NONE;
+ u32 int_en;
+
+@@ -5825,10 +5826,12 @@ static irqreturn_t abnormal_interrupt_basic(struct hns_roce_dev *hr_dev,
+ roce_write(hr_dev, ROCEE_VF_ABN_INT_ST_REG,
+ 1 << HNS_ROCE_V2_VF_INT_ST_AEQ_OVERFLOW_S);
+
++ reset_type = hr_dev->is_vf ?
++ HNAE3_VF_FUNC_RESET : HNAE3_FUNC_RESET;
++
+ /* Set reset level for reset_event() */
+ if (ops->set_default_reset_request)
+- ops->set_default_reset_request(ae_dev,
+- HNAE3_FUNC_RESET);
++ ops->set_default_reset_request(ae_dev, reset_type);
+ if (ops->reset_event)
+ ops->reset_event(pdev, NULL);
+
+--
+2.43.0
+
--- /dev/null
+From 46a35a1180e2f385923bcb66cd5fc78fd85d6406 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Sep 2024 17:34:43 +0800
+Subject: RDMA/hns: Optimize hem allocation performance
+
+From: Junxian Huang <huangjunxian6@hisilicon.com>
+
+[ Upstream commit fe51f6254d81f5a69c31df16353d6539b2b51630 ]
+
+When allocating MTT hem, for each hop level of each hem that is being
+allocated, the driver iterates the hem list to find out whether the
+bt page has been allocated in this hop level. If not, allocate a new
+one and splice it to the list. The time complexity is O(n^2) in worst
+cases.
+
+Currently the allocation for-loop uses 'unit' as the step size. This
+actually has taken into account the reuse of last-hop-level MTT bt
+pages by multiple buffer pages. Thus pages of last hop level will
+never have been allocated, so there is no need to iterate the hem list
+in last hop level.
+
+Removing this unnecessary iteration can reduce the time complexity to
+O(n).
+
+Fixes: 38389eaa4db1 ("RDMA/hns: Add mtr support for mixed multihop addressing")
+Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Link: https://patch.msgid.link/20240906093444.3571619-9-huangjunxian6@hisilicon.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hem.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c
+index 5f2b434541a2d..ce2ace2c850dc 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hem.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hem.c
+@@ -1182,10 +1182,12 @@ static int hem_list_alloc_mid_bt(struct hns_roce_dev *hr_dev,
+
+ /* config L1 bt to last bt and link them to corresponding parent */
+ for (level = 1; level < hopnum; level++) {
+- cur = hem_list_search_item(&mid_bt[level], offset);
+- if (cur) {
+- hem_ptrs[level] = cur;
+- continue;
++ if (!hem_list_is_bottom_bt(hopnum, level)) {
++ cur = hem_list_search_item(&mid_bt[level], offset);
++ if (cur) {
++ hem_ptrs[level] = cur;
++ continue;
++ }
+ }
+
+ step = hem_list_calc_ba_range(hopnum, level, unit);
+--
+2.43.0
+
--- /dev/null
+From d9e00afbc878c21c02cbb8e62b5ca9779aa840d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 21:43:52 +0800
+Subject: RDMA/hns: Refactor the abnormal interrupt handler function
+
+From: Haoyue Xu <xuhaoyue1@hisilicon.com>
+
+[ Upstream commit 75e4e716f7089558fda4ddc660fa8dbdec4eb1d3 ]
+
+Use a single function to handle the same kind of abnormal interrupts.
+
+Link: https://lore.kernel.org/r/20220714134353.16700-5-liangwenpeng@huawei.com
+Signed-off-by: Haoyue Xu <xuhaoyue1@hisilicon.com>
+Signed-off-by: Wenpeng Liang <liangwenpeng@huawei.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: 4321feefa550 ("RDMA/hns: Fix VF triggering PF reset in abnormal interrupt handler")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 35 ++++++++++++++--------
+ 1 file changed, 23 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 4c98341602067..92cff8d014cbe 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -5808,24 +5808,19 @@ static irqreturn_t hns_roce_v2_msix_interrupt_eq(int irq, void *eq_ptr)
+ return IRQ_RETVAL(int_work);
+ }
+
+-static irqreturn_t hns_roce_v2_msix_interrupt_abn(int irq, void *dev_id)
++static irqreturn_t abnormal_interrupt_basic(struct hns_roce_dev *hr_dev,
++ u32 int_st)
+ {
+- struct hns_roce_dev *hr_dev = dev_id;
+- struct device *dev = hr_dev->dev;
++ struct pci_dev *pdev = hr_dev->pci_dev;
++ struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);
++ const struct hnae3_ae_ops *ops = ae_dev->ops;
+ irqreturn_t int_work = IRQ_NONE;
+- u32 int_st;
+ u32 int_en;
+
+- /* Abnormal interrupt */
+- int_st = roce_read(hr_dev, ROCEE_VF_ABN_INT_ST_REG);
+ int_en = roce_read(hr_dev, ROCEE_VF_ABN_INT_EN_REG);
+
+ if (int_st & BIT(HNS_ROCE_V2_VF_INT_ST_AEQ_OVERFLOW_S)) {
+- struct pci_dev *pdev = hr_dev->pci_dev;
+- struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);
+- const struct hnae3_ae_ops *ops = ae_dev->ops;
+-
+- dev_err(dev, "AEQ overflow!\n");
++ dev_err(hr_dev->dev, "AEQ overflow!\n");
+
+ roce_write(hr_dev, ROCEE_VF_ABN_INT_ST_REG,
+ 1 << HNS_ROCE_V2_VF_INT_ST_AEQ_OVERFLOW_S);
+@@ -5842,12 +5837,28 @@ static irqreturn_t hns_roce_v2_msix_interrupt_abn(int irq, void *dev_id)
+
+ int_work = IRQ_HANDLED;
+ } else {
+- dev_err(dev, "There is no abnormal irq found!\n");
++ dev_err(hr_dev->dev, "there is no basic abn irq found.\n");
+ }
+
+ return IRQ_RETVAL(int_work);
+ }
+
++static irqreturn_t hns_roce_v2_msix_interrupt_abn(int irq, void *dev_id)
++{
++ struct hns_roce_dev *hr_dev = dev_id;
++ irqreturn_t int_work = IRQ_NONE;
++ u32 int_st;
++
++ int_st = roce_read(hr_dev, ROCEE_VF_ABN_INT_ST_REG);
++
++ if (int_st)
++ int_work = abnormal_interrupt_basic(hr_dev, int_st);
++ else
++ dev_err(hr_dev->dev, "there is no abnormal irq found.\n");
++
++ return IRQ_RETVAL(int_work);
++}
++
+ static void hns_roce_v2_int_mask_enable(struct hns_roce_dev *hr_dev,
+ int eq_num, u32 enable_flag)
+ {
+--
+2.43.0
+
--- /dev/null
+From 850668f8a5b1f07072bbf05409000a5cfd7d1223 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Jul 2022 21:43:49 +0800
+Subject: RDMA/hns: Remove unused abnormal interrupt of type RAS
+
+From: Haoyue Xu <xuhaoyue1@hisilicon.com>
+
+[ Upstream commit f5c25465b4f7d3badcaa5bf4a6f82f5763865b19 ]
+
+The HNS NIC driver receives and handles the abnormal interrupt of the RAS
+type generated by ROCEE, and the HNS RDMA driver does not need to handle
+this type of interrupt. Therefore, delete unused codes in the HNS RDMA
+driver.
+
+Link: https://lore.kernel.org/r/20220714134353.16700-2-liangwenpeng@huawei.com
+Signed-off-by: Haoyue Xu <xuhaoyue1@hisilicon.com>
+Signed-off-by: Wenpeng Liang <liangwenpeng@huawei.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: 4321feefa550 ("RDMA/hns: Fix VF triggering PF reset in abnormal interrupt handler")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 10 ----------
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 1 -
+ 2 files changed, 11 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 7aaf7d5be91b0..71ba2960e4b0f 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -5839,16 +5839,6 @@ static irqreturn_t hns_roce_v2_msix_interrupt_abn(int irq, void *dev_id)
+ int_en |= 1 << HNS_ROCE_V2_VF_ABN_INT_EN_S;
+ roce_write(hr_dev, ROCEE_VF_ABN_INT_EN_REG, int_en);
+
+- int_work = 1;
+- } else if (int_st & BIT(HNS_ROCE_V2_VF_INT_ST_RAS_INT_S)) {
+- dev_err(dev, "RAS interrupt!\n");
+-
+- int_st |= 1 << HNS_ROCE_V2_VF_INT_ST_RAS_INT_S;
+- roce_write(hr_dev, ROCEE_VF_ABN_INT_ST_REG, int_st);
+-
+- int_en |= 1 << HNS_ROCE_V2_VF_ABN_INT_EN_S;
+- roce_write(hr_dev, ROCEE_VF_ABN_INT_EN_REG, int_en);
+-
+ int_work = 1;
+ } else {
+ dev_err(dev, "There is no abnormal irq found!\n");
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+index 67f5b6fcfa1b1..0c120a4b48c0b 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+@@ -1445,7 +1445,6 @@ struct hns_roce_dip {
+ #define HNS_ROCE_V2_ASYNC_EQE_NUM 0x1000
+
+ #define HNS_ROCE_V2_VF_INT_ST_AEQ_OVERFLOW_S 0
+-#define HNS_ROCE_V2_VF_INT_ST_RAS_INT_S 1
+
+ #define HNS_ROCE_EQ_DB_CMD_AEQ 0x0
+ #define HNS_ROCE_EQ_DB_CMD_AEQ_ARMED 0x1
+--
+2.43.0
+
--- /dev/null
+From 244a32cdde80d8e8591a0cc5a5879b90e6fb26af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Sep 2024 21:58:05 +0500
+Subject: RDMA/irdma: fix error message in irdma_modify_qp_roce()
+
+From: Vitaliy Shevtsov <v.shevtsov@maxima.ru>
+
+[ Upstream commit 9f0eafe86ea0a589676209d0cff1a1ed49a037d3 ]
+
+Use a correct field max_dest_rd_atomic instead of max_rd_atomic for the
+error output.
+
+Found by Linux Verification Center (linuxtesting.org) with Svace.
+
+Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
+Signed-off-by: Vitaliy Shevtsov <v.shevtsov@maxima.ru>
+Link: https://lore.kernel.org/stable/20240916165817.14691-1-v.shevtsov%40maxima.ru
+Link: https://patch.msgid.link/20240916165817.14691-1-v.shevtsov@maxima.ru
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index d43833e141a02..b2bf147883edb 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -1258,7 +1258,7 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ if (attr->max_dest_rd_atomic > dev->hw_attrs.max_hw_ird) {
+ ibdev_err(&iwdev->ibdev,
+ "rd_atomic = %d, above max_hw_ird=%d\n",
+- attr->max_rd_atomic,
++ attr->max_dest_rd_atomic,
+ dev->hw_attrs.max_hw_ird);
+ return -EINVAL;
+ }
+--
+2.43.0
+
--- /dev/null
+From 50375c20dea153c70e204b6582de33b33a3bed50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Aug 2024 13:33:36 +0200
+Subject: RDMA/iwcm: Fix WARNING:at_kernel/workqueue.c:#check_flush_dependency
+
+From: Zhu Yanjun <yanjun.zhu@linux.dev>
+
+[ Upstream commit 86dfdd8288907f03c18b7fb462e0e232c4f98d89 ]
+
+In the commit aee2424246f9 ("RDMA/iwcm: Fix a use-after-free related to
+destroying CM IDs"), the function flush_workqueue is invoked to flush the
+work queue iwcm_wq.
+
+But at that time, the work queue iwcm_wq was created via the function
+alloc_ordered_workqueue without the flag WQ_MEM_RECLAIM.
+
+Because the current process is trying to flush the whole iwcm_wq, if
+iwcm_wq doesn't have the flag WQ_MEM_RECLAIM, verify that the current
+process is not reclaiming memory or running on a workqueue which doesn't
+have the flag WQ_MEM_RECLAIM as that can break forward-progress guarantee
+leading to a deadlock.
+
+The call trace is as below:
+
+[ 125.350876][ T1430] Call Trace:
+[ 125.356281][ T1430] <TASK>
+[ 125.361285][ T1430] ? __warn (kernel/panic.c:693)
+[ 125.367640][ T1430] ? check_flush_dependency (kernel/workqueue.c:3706 (discriminator 9))
+[ 125.375689][ T1430] ? report_bug (lib/bug.c:180 lib/bug.c:219)
+[ 125.382505][ T1430] ? handle_bug (arch/x86/kernel/traps.c:239)
+[ 125.388987][ T1430] ? exc_invalid_op (arch/x86/kernel/traps.c:260 (discriminator 1))
+[ 125.395831][ T1430] ? asm_exc_invalid_op (arch/x86/include/asm/idtentry.h:621)
+[ 125.403125][ T1430] ? check_flush_dependency (kernel/workqueue.c:3706 (discriminator 9))
+[ 125.410984][ T1430] ? check_flush_dependency (kernel/workqueue.c:3706 (discriminator 9))
+[ 125.418764][ T1430] __flush_workqueue (kernel/workqueue.c:3970)
+[ 125.426021][ T1430] ? __pfx___might_resched (kernel/sched/core.c:10151)
+[ 125.433431][ T1430] ? destroy_cm_id (drivers/infiniband/core/iwcm.c:375) iw_cm
+[ 125.441209][ T1430] ? __pfx___flush_workqueue (kernel/workqueue.c:3910)
+[ 125.473900][ T1430] ? _raw_spin_lock_irqsave (arch/x86/include/asm/atomic.h:107 include/linux/atomic/atomic-arch-fallback.h:2170 include/linux/atomic/atomic-instrumented.h:1302 include/asm-generic/qspinlock.h:111 include/linux/spinlock.h:187 include/linux/spinlock_api_smp.h:111 kernel/locking/spinlock.c:162)
+[ 125.473909][ T1430] ? __pfx__raw_spin_lock_irqsave (kernel/locking/spinlock.c:161)
+[ 125.482537][ T1430] _destroy_id (drivers/infiniband/core/cma.c:2044) rdma_cm
+[ 125.495072][ T1430] nvme_rdma_free_queue (drivers/nvme/host/rdma.c:656 drivers/nvme/host/rdma.c:650) nvme_rdma
+[ 125.505827][ T1430] nvme_rdma_reset_ctrl_work (drivers/nvme/host/rdma.c:2180) nvme_rdma
+[ 125.505831][ T1430] process_one_work (kernel/workqueue.c:3231)
+[ 125.515122][ T1430] worker_thread (kernel/workqueue.c:3306 kernel/workqueue.c:3393)
+[ 125.515127][ T1430] ? __pfx_worker_thread (kernel/workqueue.c:3339)
+[ 125.531837][ T1430] kthread (kernel/kthread.c:389)
+[ 125.539864][ T1430] ? __pfx_kthread (kernel/kthread.c:342)
+[ 125.550628][ T1430] ret_from_fork (arch/x86/kernel/process.c:147)
+[ 125.558840][ T1430] ? __pfx_kthread (kernel/kthread.c:342)
+[ 125.558844][ T1430] ret_from_fork_asm (arch/x86/entry/entry_64.S:257)
+[ 125.566487][ T1430] </TASK>
+[ 125.566488][ T1430] ---[ end trace 0000000000000000 ]---
+
+Fixes: aee2424246f9 ("RDMA/iwcm: Fix a use-after-free related to destroying CM IDs")
+Link: https://patch.msgid.link/r/20240820113336.19860-1-yanjun.zhu@linux.dev
+Reported-by: kernel test robot <oliver.sang@intel.com>
+Closes: https://lore.kernel.org/oe-lkp/202408151633.fc01893c-oliver.sang@intel.com
+Tested-by: kernel test robot <oliver.sang@intel.com>
+Signed-off-by: Zhu Yanjun <yanjun.zhu@linux.dev>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/iwcm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c
+index 2d09d1be38f19..3e4941754b48d 100644
+--- a/drivers/infiniband/core/iwcm.c
++++ b/drivers/infiniband/core/iwcm.c
+@@ -1191,7 +1191,7 @@ static int __init iw_cm_init(void)
+ if (ret)
+ return ret;
+
+- iwcm_wq = alloc_ordered_workqueue("iw_cm_wq", 0);
++ iwcm_wq = alloc_ordered_workqueue("iw_cm_wq", WQ_MEM_RECLAIM);
+ if (!iwcm_wq)
+ goto err_alloc;
+
+--
+2.43.0
+
--- /dev/null
+From 4b6558eefc16a520c41be854a882dc895976a328 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Aug 2024 13:22:12 +0200
+Subject: RDMA/rtrs-clt: Reset cid to con_num - 1 to stay in bounds
+
+From: Md Haris Iqbal <haris.iqbal@ionos.com>
+
+[ Upstream commit 3e4289b29e216a55d08a89e126bc0b37cbad9f38 ]
+
+In the function init_conns(), after the create_con() and create_cm() for
+loop if something fails. In the cleanup for loop after the destroy tag, we
+access out of bound memory because cid is set to clt_path->s.con_num.
+
+This commits resets the cid to clt_path->s.con_num - 1, to stay in bounds
+in the cleanup loop later.
+
+Fixes: 6a98d71daea1 ("RDMA/rtrs: client: main functionality")
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Grzegorz Prajsner <grzegorz.prajsner@ionos.com>
+Link: https://patch.msgid.link/20240821112217.41827-7-haris.iqbal@ionos.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-clt.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+index 8f496c88bfe7e..e8f5a1f104cfa 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+@@ -2338,6 +2338,12 @@ static int init_conns(struct rtrs_clt_path *clt_path)
+ if (err)
+ goto destroy;
+ }
++
++ /*
++ * Set the cid to con_num - 1, since if we fail later, we want to stay in bounds.
++ */
++ cid = clt_path->s.con_num - 1;
++
+ err = alloc_path_reqs(clt_path);
+ if (err)
+ goto destroy;
+--
+2.43.0
+
--- /dev/null
+From ca43f041cdf41f9feddef5577c5193710aa9813f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Aug 2024 13:22:10 +0200
+Subject: RDMA/rtrs: Reset hb_missed_cnt after receiving other traffic from
+ peer
+
+From: Jack Wang <jinpu.wang@ionos.com>
+
+[ Upstream commit 3258cbbd86deaa2675e1799bc3d18bd1ef472641 ]
+
+Reset hb_missed_cnt after receiving traffic from other peer, so
+hb is more robust again high load on host or network.
+
+Fixes: 6a98d71daea1 ("RDMA/rtrs: client: main functionality")
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Md Haris Iqbal <haris.iqbal@ionos.com>
+Signed-off-by: Grzegorz Prajsner <grzegorz.prajsner@ionos.com>
+Link: https://patch.msgid.link/20240821112217.41827-5-haris.iqbal@ionos.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/ulp/rtrs/rtrs-clt.c | 3 ++-
+ drivers/infiniband/ulp/rtrs/rtrs-srv.c | 1 +
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+index 3f4ef6e4a89be..8f496c88bfe7e 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+@@ -625,6 +625,7 @@ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+ */
+ if (WARN_ON(wc->wr_cqe->done != rtrs_clt_rdma_done))
+ return;
++ clt_path->s.hb_missed_cnt = 0;
+ rtrs_from_imm(be32_to_cpu(wc->ex.imm_data),
+ &imm_type, &imm_payload);
+ if (imm_type == RTRS_IO_RSP_IMM ||
+@@ -642,7 +643,6 @@ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+ return rtrs_clt_recv_done(con, wc);
+ } else if (imm_type == RTRS_HB_ACK_IMM) {
+ WARN_ON(con->c.cid);
+- clt_path->s.hb_missed_cnt = 0;
+ clt_path->s.hb_cur_latency =
+ ktime_sub(ktime_get(), clt_path->s.hb_last_sent);
+ if (clt_path->flags & RTRS_MSG_NEW_RKEY_F)
+@@ -669,6 +669,7 @@ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+ /*
+ * Key invalidations from server side
+ */
++ clt_path->s.hb_missed_cnt = 0;
+ WARN_ON(!(wc->wc_flags & IB_WC_WITH_INVALIDATE ||
+ wc->wc_flags & IB_WC_WITH_IMM));
+ WARN_ON(wc->wr_cqe->done != rtrs_clt_rdma_done);
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+index 27bf2b2da9fd6..1af6db9a6511a 100644
+--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c
++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+@@ -1241,6 +1241,7 @@ static void rtrs_srv_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
+ */
+ if (WARN_ON(wc->wr_cqe != &io_comp_cqe))
+ return;
++ srv_path->s.hb_missed_cnt = 0;
+ err = rtrs_post_recv_empty(&con->c, &io_comp_cqe);
+ if (err) {
+ rtrs_err(s, "rtrs_post_recv(), err: %d\n", err);
+--
+2.43.0
+
--- /dev/null
+From b945e4a5c1efe01e24afc3e893a45c2c356f16d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jul 2024 16:36:11 +0800
+Subject: remoteproc: imx_rproc: Correct ddr alias for i.MX8M
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit c901f817792822eda9cec23814a4621fa3e66695 ]
+
+The DDR Alias address should be 0x40000000 according to RM, so correct
+it.
+
+Fixes: 4ab8f9607aad ("remoteproc: imx_rproc: support i.MX8MQ/M")
+Reported-by: Terry Lv <terry.lv@nxp.com>
+Reviewed-by: Iuliana Prodan <iuliana.prodan@nxp.com>
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
+Link: https://lore.kernel.org/r/20240719-imx_rproc-v2-1-10d0268c7eb1@nxp.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/imx_rproc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
+index d5ce97e75f027..fec093b3f5e10 100644
+--- a/drivers/remoteproc/imx_rproc.c
++++ b/drivers/remoteproc/imx_rproc.c
+@@ -158,7 +158,7 @@ static const struct imx_rproc_att imx_rproc_att_imx8mq[] = {
+ /* QSPI Code - alias */
+ { 0x08000000, 0x08000000, 0x08000000, 0 },
+ /* DDR (Code) - alias */
+- { 0x10000000, 0x80000000, 0x0FFE0000, 0 },
++ { 0x10000000, 0x40000000, 0x0FFE0000, 0 },
+ /* TCML */
+ { 0x1FFE0000, 0x007E0000, 0x00020000, ATT_OWN | ATT_IOMEM},
+ /* TCMU */
+--
+2.43.0
+
--- /dev/null
+From ad79b342d952e5f5287e60dcf0a81b5c3e4fb5db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jul 2024 16:36:13 +0800
+Subject: remoteproc: imx_rproc: Initialize workqueue earlier
+
+From: Peng Fan <peng.fan@nxp.com>
+
+[ Upstream commit 858e57c1d3dd7b92cc0fa692ba130a0a5d57e49d ]
+
+Initialize workqueue before requesting mailbox channel, otherwise if
+mailbox interrupt comes before workqueue ready, the imx_rproc_rx_callback
+will trigger issue.
+
+Fixes: 2df7062002d0 ("remoteproc: imx_proc: enable virtio/mailbox")
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
+Link: https://lore.kernel.org/r/20240719-imx_rproc-v2-3-10d0268c7eb1@nxp.com
+Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/remoteproc/imx_rproc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
+index fec093b3f5e10..c45c87a94d62a 100644
+--- a/drivers/remoteproc/imx_rproc.c
++++ b/drivers/remoteproc/imx_rproc.c
+@@ -792,6 +792,8 @@ static int imx_rproc_probe(struct platform_device *pdev)
+ goto err_put_rproc;
+ }
+
++ INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
++
+ ret = imx_rproc_xtr_mbox_init(rproc);
+ if (ret)
+ goto err_put_wkq;
+@@ -810,8 +812,6 @@ static int imx_rproc_probe(struct platform_device *pdev)
+ if (ret)
+ goto err_put_mbox;
+
+- INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
+-
+ if (rproc->state != RPROC_DETACHED)
+ rproc->auto_boot = of_property_read_bool(np, "fsl,auto-boot");
+
+--
+2.43.0
+
--- /dev/null
+From 83bc234e44be7abfdcefe172eba39a505fa0df7e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Aug 2024 16:14:24 +0200
+Subject: reset: berlin: fix OF node leak in probe() error path
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit 5f58a88cc91075be38cec69b7cb70aaa4ba69e8b ]
+
+Driver is leaking OF node reference on memory allocation failure.
+Acquire the OF node reference after memory allocation to fix this and
+keep it simple.
+
+Fixes: aed6f3cadc86 ("reset: berlin: convert to a platform driver")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Link: https://lore.kernel.org/r/20240825-reset-cleanup-scoped-v1-1-03f6d834f8c0@linaro.org
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/reset/reset-berlin.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/reset/reset-berlin.c b/drivers/reset/reset-berlin.c
+index 2537ec05eceef..578fe867080ce 100644
+--- a/drivers/reset/reset-berlin.c
++++ b/drivers/reset/reset-berlin.c
+@@ -68,13 +68,14 @@ static int berlin_reset_xlate(struct reset_controller_dev *rcdev,
+
+ static int berlin2_reset_probe(struct platform_device *pdev)
+ {
+- struct device_node *parent_np = of_get_parent(pdev->dev.of_node);
++ struct device_node *parent_np;
+ struct berlin_reset_priv *priv;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
++ parent_np = of_get_parent(pdev->dev.of_node);
+ priv->regmap = syscon_node_to_regmap(parent_np);
+ of_node_put(parent_np);
+ if (IS_ERR(priv->regmap))
+--
+2.43.0
+
--- /dev/null
+From e64e2cf033d5da5695f488f5f6519976eb0d2d8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Aug 2024 16:14:25 +0200
+Subject: reset: k210: fix OF node leak in probe() error path
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit b14e40f5dc7cd0dd7e958010e6ca9ad32ff2ddad ]
+
+Driver is leaking OF node reference on memory allocation failure.
+Acquire the OF node reference after memory allocation to fix this and
+keep it simple.
+
+Fixes: 5a2308da9f60 ("riscv: Add Canaan Kendryte K210 reset controller")
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
+Link: https://lore.kernel.org/r/20240825-reset-cleanup-scoped-v1-2-03f6d834f8c0@linaro.org
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/reset/reset-k210.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/reset/reset-k210.c b/drivers/reset/reset-k210.c
+index 1b6e03522b40d..b0f4546b2b1e5 100644
+--- a/drivers/reset/reset-k210.c
++++ b/drivers/reset/reset-k210.c
+@@ -91,7 +91,7 @@ static const struct reset_control_ops k210_rst_ops = {
+ static int k210_rst_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+- struct device_node *parent_np = of_get_parent(dev->of_node);
++ struct device_node *parent_np;
+ struct k210_rst *ksr;
+
+ dev_info(dev, "K210 reset controller\n");
+@@ -100,6 +100,7 @@ static int k210_rst_probe(struct platform_device *pdev)
+ if (!ksr)
+ return -ENOMEM;
+
++ parent_np = of_get_parent(dev->of_node);
+ ksr->map = syscon_node_to_regmap(parent_np);
+ of_node_put(parent_np);
+ if (IS_ERR(ksr->map))
+--
+2.43.0
+
--- /dev/null
+From 0c56b8b675de80750821a7b61a1957f5e634e0db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Sep 2024 15:05:18 +0200
+Subject: Revert "dm: requeue IO if mapping table not yet available"
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+[ Upstream commit c8691cd0fc11197515ed148de0780d927bfca38b ]
+
+This reverts commit fa247089de9936a46e290d4724cb5f0b845600f5.
+
+The following sequence of commands causes a livelock - there will be
+workqueue process looping and consuming 100% CPU:
+
+dmsetup create --notable test
+truncate -s 1MiB testdata
+losetup /dev/loop0 testdata
+dmsetup load test --table '0 2048 linear /dev/loop0 0'
+dd if=/dev/zero of=/dev/dm-0 bs=16k count=1 conv=fdatasync
+
+The livelock is caused by the commit fa247089de99. The commit claims that
+it fixes a race condition, however, it is unknown what the actual race
+condition is and what program is involved in the race condition.
+
+When the inactive table is loaded, the nodes /dev/dm-0 and
+/sys/block/dm-0 are created. /dev/dm-0 has zero size at this point. When
+the device is suspended and resumed, the nodes /dev/mapper/test and
+/dev/disk/* are created.
+
+If some program opens a block device before it is created by dmsetup or
+lvm, the program is buggy, so dm could just report an error as it used to
+do before.
+
+Reported-by: Zdenek Kabelac <zkabelac@redhat.com>
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Fixes: fa247089de99 ("dm: requeue IO if mapping table not yet available")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-rq.c | 4 +++-
+ drivers/md/dm.c | 11 ++++++++---
+ 2 files changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c
+index 53a9b16c7b2e6..7eedcd012f45f 100644
+--- a/drivers/md/dm-rq.c
++++ b/drivers/md/dm-rq.c
+@@ -504,8 +504,10 @@ static blk_status_t dm_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
+
+ map = dm_get_live_table(md, &srcu_idx);
+ if (unlikely(!map)) {
++ DMERR_LIMIT("%s: mapping table unavailable, erroring io",
++ dm_device_name(md));
+ dm_put_live_table(md, srcu_idx);
+- return BLK_STS_RESOURCE;
++ return BLK_STS_IOERR;
+ }
+ ti = dm_table_find_target(map, 0);
+ dm_put_live_table(md, srcu_idx);
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 8199166ca8620..8b192fc1f798c 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -1593,10 +1593,15 @@ static blk_qc_t dm_submit_bio(struct bio *bio)
+ struct dm_table *map;
+
+ map = dm_get_live_table(md, &srcu_idx);
++ if (unlikely(!map)) {
++ DMERR_LIMIT("%s: mapping table unavailable, erroring io",
++ dm_device_name(md));
++ bio_io_error(bio);
++ goto out;
++ }
+
+- /* If suspended, or map not yet available, queue this IO for later */
+- if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) ||
+- unlikely(!map)) {
++ /* If suspended, queue this IO for later */
++ if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags))) {
+ if (bio->bi_opf & REQ_NOWAIT)
+ bio_wouldblock_error(bio);
+ else if (bio->bi_opf & REQ_RAHEAD)
+--
+2.43.0
+
--- /dev/null
+From 4e4b41e6482581137e9eb25a659bd1765798ed66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jul 2024 11:28:46 +0800
+Subject: riscv: Fix fp alignment bug in perf_callchain_user()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 22ab08955ea13be04a8efd20cc30890e0afaa49c ]
+
+The standard RISC-V calling convention said:
+ "The stack grows downward and the stack pointer is always
+ kept 16-byte aligned".
+
+So perf_callchain_user() should check whether 16-byte aligned for fp.
+
+Link: https://riscv.org/wp-content/uploads/2015/01/riscv-calling.pdf
+
+Fixes: dbeb90b0c1eb ("riscv: Add perf callchain support")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Cc: Björn Töpel <bjorn@kernel.org>
+Link: https://lore.kernel.org/r/20240708032847.2998158-2-ruanjinjie@huawei.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/perf_callchain.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/kernel/perf_callchain.c b/arch/riscv/kernel/perf_callchain.c
+index 357f985041cb9..31b105fb77f1f 100644
+--- a/arch/riscv/kernel/perf_callchain.c
++++ b/arch/riscv/kernel/perf_callchain.c
+@@ -67,7 +67,7 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
+ perf_callchain_store(entry, regs->epc);
+
+ fp = user_backtrace(entry, fp, regs->ra);
+- while (fp && !(fp & 0x3) && entry->nr < entry->max_stack)
++ while (fp && !(fp & 0x7) && entry->nr < entry->max_stack)
+ fp = user_backtrace(entry, fp, 0);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From c3214f802860963cb0eacf7635f0a44156b4afe0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Aug 2024 14:29:05 +0300
+Subject: scsi: elx: libefc: Fix potential use after free in
+ efc_nport_vport_del()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 2e4b02fad094976763af08fec2c620f4f8edd9ae ]
+
+The kref_put() function will call nport->release if the refcount drops to
+zero. The nport->release release function is _efc_nport_free() which frees
+"nport". But then we dereference "nport" on the next line which is a use
+after free. Re-order these lines to avoid the use after free.
+
+Fixes: fcd427303eb9 ("scsi: elx: libefc: SLI and FC PORT state machine interfaces")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/r/b666ab26-6581-4213-9a3d-32a9147f0399@stanley.mountain
+Reviewed-by: Daniel Wagner <dwagner@suse.de>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/elx/libefc/efc_nport.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/elx/libefc/efc_nport.c b/drivers/scsi/elx/libefc/efc_nport.c
+index 2e83a667901fe..1a7437f4328e8 100644
+--- a/drivers/scsi/elx/libefc/efc_nport.c
++++ b/drivers/scsi/elx/libefc/efc_nport.c
+@@ -705,9 +705,9 @@ efc_nport_vport_del(struct efc *efc, struct efc_domain *domain,
+ spin_lock_irqsave(&efc->lock, flags);
+ list_for_each_entry(nport, &domain->nport_list, list_entry) {
+ if (nport->wwpn == wwpn && nport->wwnn == wwnn) {
+- kref_put(&nport->ref, nport->release);
+ /* Shutdown this NPORT */
+ efc_sm_post_event(&nport->sm, EFC_EVT_SHUTDOWN, NULL);
++ kref_put(&nport->ref, nport->release);
+ break;
+ }
+ }
+--
+2.43.0
+
--- /dev/null
+From a5c6abb5658b40386cea3d83fe625fe3caed3679 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Feb 2022 11:50:36 -0800
+Subject: scsi: NCR5380: Add SCp members to struct NCR5380_cmd
+
+From: Finn Thain <fthain@linux-m68k.org>
+
+[ Upstream commit ff1269cb3d978655fb4f61f87d08a46af9854567 ]
+
+This is necessary for the eventual removal of SCp from struct scsi_cmnd.
+
+Link: https://lore.kernel.org/r/20220218195117.25689-9-bvanassche@acm.org
+Cc: Michael Schmitz <schmitzmic@gmail.com>
+Cc: Ondrej Zary <linux@zary.sk>
+Suggested-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Finn Thain <fthain@linux-m68k.org>
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: 5768718da941 ("scsi: NCR5380: Check for phase match during PDMA fixup")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/NCR5380.c | 94 +++++++++++++++++++--------------------
+ drivers/scsi/NCR5380.h | 11 +++++
+ drivers/scsi/atari_scsi.c | 4 +-
+ drivers/scsi/g_NCR5380.c | 4 +-
+ drivers/scsi/mac_scsi.c | 7 +--
+ drivers/scsi/sun3_scsi.c | 2 +-
+ 6 files changed, 66 insertions(+), 56 deletions(-)
+
+diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
+index a85589a2a8afb..98b1a98db90f6 100644
+--- a/drivers/scsi/NCR5380.c
++++ b/drivers/scsi/NCR5380.c
+@@ -84,8 +84,7 @@
+ * On command termination, the done function will be called as
+ * appropriate.
+ *
+- * SCSI pointers are maintained in the SCp field of SCSI command
+- * structures, being initialized after the command is connected
++ * The command data pointer is initialized after the command is connected
+ * in NCR5380_select, and set as appropriate in NCR5380_information_transfer.
+ * Note that in violation of the standard, an implicit SAVE POINTERS operation
+ * is done, since some BROKEN disks fail to issue an explicit SAVE POINTERS.
+@@ -145,40 +144,38 @@ static void bus_reset_cleanup(struct Scsi_Host *);
+
+ static inline void initialize_SCp(struct scsi_cmnd *cmd)
+ {
+- /*
+- * Initialize the Scsi Pointer field so that all of the commands in the
+- * various queues are valid.
+- */
++ struct NCR5380_cmd *ncmd = NCR5380_to_ncmd(cmd);
+
+ if (scsi_bufflen(cmd)) {
+- cmd->SCp.buffer = scsi_sglist(cmd);
+- cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
+- cmd->SCp.this_residual = cmd->SCp.buffer->length;
++ ncmd->buffer = scsi_sglist(cmd);
++ ncmd->ptr = sg_virt(ncmd->buffer);
++ ncmd->this_residual = ncmd->buffer->length;
+ } else {
+- cmd->SCp.buffer = NULL;
+- cmd->SCp.ptr = NULL;
+- cmd->SCp.this_residual = 0;
++ ncmd->buffer = NULL;
++ ncmd->ptr = NULL;
++ ncmd->this_residual = 0;
+ }
+
+- cmd->SCp.Status = 0;
+- cmd->SCp.Message = 0;
++ ncmd->status = 0;
++ ncmd->message = 0;
+ }
+
+-static inline void advance_sg_buffer(struct scsi_cmnd *cmd)
++static inline void advance_sg_buffer(struct NCR5380_cmd *ncmd)
+ {
+- struct scatterlist *s = cmd->SCp.buffer;
++ struct scatterlist *s = ncmd->buffer;
+
+- if (!cmd->SCp.this_residual && s && !sg_is_last(s)) {
+- cmd->SCp.buffer = sg_next(s);
+- cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
+- cmd->SCp.this_residual = cmd->SCp.buffer->length;
++ if (!ncmd->this_residual && s && !sg_is_last(s)) {
++ ncmd->buffer = sg_next(s);
++ ncmd->ptr = sg_virt(ncmd->buffer);
++ ncmd->this_residual = ncmd->buffer->length;
+ }
+ }
+
+ static inline void set_resid_from_SCp(struct scsi_cmnd *cmd)
+ {
+- int resid = cmd->SCp.this_residual;
+- struct scatterlist *s = cmd->SCp.buffer;
++ struct NCR5380_cmd *ncmd = NCR5380_to_ncmd(cmd);
++ int resid = ncmd->this_residual;
++ struct scatterlist *s = ncmd->buffer;
+
+ if (s)
+ while (!sg_is_last(s)) {
+@@ -564,7 +561,7 @@ static int NCR5380_queue_command(struct Scsi_Host *instance,
+ struct scsi_cmnd *cmd)
+ {
+ struct NCR5380_hostdata *hostdata = shost_priv(instance);
+- struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
++ struct NCR5380_cmd *ncmd = NCR5380_to_ncmd(cmd);
+ unsigned long flags;
+
+ #if (NDEBUG & NDEBUG_NO_WRITE)
+@@ -672,7 +669,7 @@ static struct scsi_cmnd *dequeue_next_cmd(struct Scsi_Host *instance)
+ static void requeue_cmd(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
+ {
+ struct NCR5380_hostdata *hostdata = shost_priv(instance);
+- struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
++ struct NCR5380_cmd *ncmd = NCR5380_to_ncmd(cmd);
+
+ if (hostdata->sensing == cmd) {
+ scsi_eh_restore_cmnd(cmd, &hostdata->ses);
+@@ -757,6 +754,7 @@ static void NCR5380_main(struct work_struct *work)
+ static void NCR5380_dma_complete(struct Scsi_Host *instance)
+ {
+ struct NCR5380_hostdata *hostdata = shost_priv(instance);
++ struct NCR5380_cmd *ncmd = NCR5380_to_ncmd(hostdata->connected);
+ int transferred;
+ unsigned char **data;
+ int *count;
+@@ -764,7 +762,7 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance)
+ unsigned char p;
+
+ if (hostdata->read_overruns) {
+- p = hostdata->connected->SCp.phase;
++ p = ncmd->phase;
+ if (p & SR_IO) {
+ udelay(10);
+ if ((NCR5380_read(BUS_AND_STATUS_REG) &
+@@ -801,8 +799,8 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance)
+ transferred = hostdata->dma_len - NCR5380_dma_residual(hostdata);
+ hostdata->dma_len = 0;
+
+- data = (unsigned char **)&hostdata->connected->SCp.ptr;
+- count = &hostdata->connected->SCp.this_residual;
++ data = (unsigned char **)&ncmd->ptr;
++ count = &ncmd->this_residual;
+ *data += transferred;
+ *count -= transferred;
+
+@@ -1498,7 +1496,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
+ return -1;
+ }
+
+- hostdata->connected->SCp.phase = p;
++ NCR5380_to_ncmd(hostdata->connected)->phase = p;
+
+ if (p & SR_IO) {
+ if (hostdata->read_overruns)
+@@ -1690,7 +1688,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
+ #endif
+
+ while ((cmd = hostdata->connected)) {
+- struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd);
++ struct NCR5380_cmd *ncmd = NCR5380_to_ncmd(cmd);
+
+ tmp = NCR5380_read(STATUS_REG);
+ /* We only have a valid SCSI phase when REQ is asserted */
+@@ -1705,17 +1703,17 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
+ sun3_dma_setup_done != cmd) {
+ int count;
+
+- advance_sg_buffer(cmd);
++ advance_sg_buffer(ncmd);
+
+ count = sun3scsi_dma_xfer_len(hostdata, cmd);
+
+ if (count > 0) {
+ if (cmd->sc_data_direction == DMA_TO_DEVICE)
+ sun3scsi_dma_send_setup(hostdata,
+- cmd->SCp.ptr, count);
++ ncmd->ptr, count);
+ else
+ sun3scsi_dma_recv_setup(hostdata,
+- cmd->SCp.ptr, count);
++ ncmd->ptr, count);
+ sun3_dma_setup_done = cmd;
+ }
+ #ifdef SUN3_SCSI_VME
+@@ -1755,11 +1753,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
+ * scatter-gather list, move onto the next one.
+ */
+
+- advance_sg_buffer(cmd);
++ advance_sg_buffer(ncmd);
+ dsprintk(NDEBUG_INFORMATION, instance,
+ "this residual %d, sg ents %d\n",
+- cmd->SCp.this_residual,
+- sg_nents(cmd->SCp.buffer));
++ ncmd->this_residual,
++ sg_nents(ncmd->buffer));
+
+ /*
+ * The preferred transfer method is going to be
+@@ -1778,7 +1776,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
+ if (transfersize > 0) {
+ len = transfersize;
+ if (NCR5380_transfer_dma(instance, &phase,
+- &len, (unsigned char **)&cmd->SCp.ptr)) {
++ &len, (unsigned char **)&ncmd->ptr)) {
+ /*
+ * If the watchdog timer fires, all future
+ * accesses to this device will use the
+@@ -1794,13 +1792,13 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
+ /* Transfer a small chunk so that the
+ * irq mode lock is not held too long.
+ */
+- transfersize = min(cmd->SCp.this_residual,
++ transfersize = min(ncmd->this_residual,
+ NCR5380_PIO_CHUNK_SIZE);
+ len = transfersize;
+ NCR5380_transfer_pio(instance, &phase, &len,
+- (unsigned char **)&cmd->SCp.ptr,
++ (unsigned char **)&ncmd->ptr,
+ 0);
+- cmd->SCp.this_residual -= transfersize - len;
++ ncmd->this_residual -= transfersize - len;
+ }
+ #ifdef CONFIG_SUN3
+ if (sun3_dma_setup_done == cmd)
+@@ -1811,7 +1809,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
+ len = 1;
+ data = &tmp;
+ NCR5380_transfer_pio(instance, &phase, &len, &data, 0);
+- cmd->SCp.Message = tmp;
++ ncmd->message = tmp;
+
+ switch (tmp) {
+ case ABORT:
+@@ -1828,15 +1826,15 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
+ hostdata->connected = NULL;
+ hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
+
+- set_status_byte(cmd, cmd->SCp.Status);
++ set_status_byte(cmd, ncmd->status);
+
+ set_resid_from_SCp(cmd);
+
+ if (cmd->cmnd[0] == REQUEST_SENSE)
+ complete_cmd(instance, cmd);
+ else {
+- if (cmd->SCp.Status == SAM_STAT_CHECK_CONDITION ||
+- cmd->SCp.Status == SAM_STAT_COMMAND_TERMINATED) {
++ if (ncmd->status == SAM_STAT_CHECK_CONDITION ||
++ ncmd->status == SAM_STAT_COMMAND_TERMINATED) {
+ dsprintk(NDEBUG_QUEUES, instance, "autosense: adding cmd %p to tail of autosense queue\n",
+ cmd);
+ list_add_tail(&ncmd->list,
+@@ -2000,7 +1998,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
+ len = 1;
+ data = &tmp;
+ NCR5380_transfer_pio(instance, &phase, &len, &data, 0);
+- cmd->SCp.Status = tmp;
++ ncmd->status = tmp;
+ break;
+ default:
+ shost_printk(KERN_ERR, instance, "unknown phase\n");
+@@ -2153,17 +2151,17 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
+ if (sun3_dma_setup_done != tmp) {
+ int count;
+
+- advance_sg_buffer(tmp);
++ advance_sg_buffer(ncmd);
+
+ count = sun3scsi_dma_xfer_len(hostdata, tmp);
+
+ if (count > 0) {
+ if (tmp->sc_data_direction == DMA_TO_DEVICE)
+ sun3scsi_dma_send_setup(hostdata,
+- tmp->SCp.ptr, count);
++ ncmd->ptr, count);
+ else
+ sun3scsi_dma_recv_setup(hostdata,
+- tmp->SCp.ptr, count);
++ ncmd->ptr, count);
+ sun3_dma_setup_done = tmp;
+ }
+ }
+@@ -2206,7 +2204,7 @@ static bool list_del_cmd(struct list_head *haystack,
+ struct scsi_cmnd *needle)
+ {
+ if (list_find_cmd(haystack, needle)) {
+- struct NCR5380_cmd *ncmd = scsi_cmd_priv(needle);
++ struct NCR5380_cmd *ncmd = NCR5380_to_ncmd(needle);
+
+ list_del(&ncmd->list);
+ return true;
+diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
+index 8a3b41932288e..27b3612a9a19f 100644
+--- a/drivers/scsi/NCR5380.h
++++ b/drivers/scsi/NCR5380.h
+@@ -227,6 +227,12 @@ struct NCR5380_hostdata {
+ };
+
+ struct NCR5380_cmd {
++ char *ptr;
++ int this_residual;
++ struct scatterlist *buffer;
++ int status;
++ int message;
++ int phase;
+ struct list_head list;
+ };
+
+@@ -242,6 +248,11 @@ static inline struct scsi_cmnd *NCR5380_to_scmd(struct NCR5380_cmd *ncmd_ptr)
+ return ((struct scsi_cmnd *)ncmd_ptr) - 1;
+ }
+
++static inline struct NCR5380_cmd *NCR5380_to_ncmd(struct scsi_cmnd *cmd)
++{
++ return scsi_cmd_priv(cmd);
++}
++
+ #ifndef NDEBUG
+ #define NDEBUG (0)
+ #endif
+diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c
+index 95d7a35860836..cc6f7761b2ed0 100644
+--- a/drivers/scsi/atari_scsi.c
++++ b/drivers/scsi/atari_scsi.c
+@@ -538,7 +538,7 @@ static int falcon_classify_cmd(struct scsi_cmnd *cmd)
+ static int atari_scsi_dma_xfer_len(struct NCR5380_hostdata *hostdata,
+ struct scsi_cmnd *cmd)
+ {
+- int wanted_len = cmd->SCp.this_residual;
++ int wanted_len = NCR5380_to_ncmd(cmd)->this_residual;
+ int possible_len, limit;
+
+ if (wanted_len < DMA_MIN_SIZE)
+@@ -610,7 +610,7 @@ static int atari_scsi_dma_xfer_len(struct NCR5380_hostdata *hostdata,
+ }
+
+ /* Last step: apply the hard limit on DMA transfers */
+- limit = (atari_dma_buffer && !STRAM_ADDR(virt_to_phys(cmd->SCp.ptr))) ?
++ limit = (atari_dma_buffer && !STRAM_ADDR(virt_to_phys(NCR5380_to_ncmd(cmd)->ptr))) ?
+ STRAM_BUFFER_SIZE : 255*512;
+ if (possible_len > limit)
+ possible_len = limit;
+diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
+index 7ba3c9312731d..aac6a4c011528 100644
+--- a/drivers/scsi/g_NCR5380.c
++++ b/drivers/scsi/g_NCR5380.c
+@@ -663,7 +663,7 @@ static inline int generic_NCR5380_psend(struct NCR5380_hostdata *hostdata,
+ static int generic_NCR5380_dma_xfer_len(struct NCR5380_hostdata *hostdata,
+ struct scsi_cmnd *cmd)
+ {
+- int transfersize = cmd->SCp.this_residual;
++ int transfersize = NCR5380_to_ncmd(cmd)->this_residual;
+
+ if (hostdata->flags & FLAG_NO_PSEUDO_DMA)
+ return 0;
+@@ -675,7 +675,7 @@ static int generic_NCR5380_dma_xfer_len(struct NCR5380_hostdata *hostdata,
+ /* Limit PDMA send to 512 B to avoid random corruption on DTC3181E */
+ if (hostdata->board == BOARD_DTC3181E &&
+ cmd->sc_data_direction == DMA_TO_DEVICE)
+- transfersize = min(cmd->SCp.this_residual, 512);
++ transfersize = min(transfersize, 512);
+
+ return min(transfersize, DMA_MAX_SIZE);
+ }
+diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c
+index 5c808fbc6ce2c..bae529fc1c3db 100644
+--- a/drivers/scsi/mac_scsi.c
++++ b/drivers/scsi/mac_scsi.c
+@@ -404,11 +404,12 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
+ static int macscsi_dma_xfer_len(struct NCR5380_hostdata *hostdata,
+ struct scsi_cmnd *cmd)
+ {
+- if (hostdata->flags & FLAG_NO_PSEUDO_DMA ||
+- cmd->SCp.this_residual < setup_use_pdma)
++ int resid = NCR5380_to_ncmd(cmd)->this_residual;
++
++ if (hostdata->flags & FLAG_NO_PSEUDO_DMA || resid < setup_use_pdma)
+ return 0;
+
+- return cmd->SCp.this_residual;
++ return resid;
+ }
+
+ static int macscsi_dma_residual(struct NCR5380_hostdata *hostdata)
+diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c
+index f7f724a3ff1d4..5b28dd7ebdddf 100644
+--- a/drivers/scsi/sun3_scsi.c
++++ b/drivers/scsi/sun3_scsi.c
+@@ -334,7 +334,7 @@ static int sun3scsi_dma_residual(struct NCR5380_hostdata *hostdata)
+ static int sun3scsi_dma_xfer_len(struct NCR5380_hostdata *hostdata,
+ struct scsi_cmnd *cmd)
+ {
+- int wanted_len = cmd->SCp.this_residual;
++ int wanted_len = NCR5380_to_ncmd(cmd)->this_residual;
+
+ if (wanted_len < DMA_MIN_SIZE || blk_rq_is_passthrough(scsi_cmd_to_rq(cmd)))
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From 197c42383daf1e53552a3137bbb4a01ccd6f6e02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Aug 2024 13:36:28 +1000
+Subject: scsi: NCR5380: Check for phase match during PDMA fixup
+
+From: Finn Thain <fthain@linux-m68k.org>
+
+[ Upstream commit 5768718da9417331803fc4bc090544c2a93b88dc ]
+
+It's not an error for a target to change the bus phase during a transfer.
+Unfortunately, the FLAG_DMA_FIXUP workaround does not allow for that -- a
+phase change produces a DRQ timeout error and the device borken flag will
+be set.
+
+Check the phase match bit during FLAG_DMA_FIXUP processing. Don't forget to
+decrement the command residual. While we are here, change shost_printk()
+into scmd_printk() for better consistency with other DMA error messages.
+
+Tested-by: Stan Johnson <userm57@yahoo.com>
+Fixes: 55181be8ced1 ("ncr5380: Replace redundant flags with FLAG_NO_DMA_FIXUP")
+Signed-off-by: Finn Thain <fthain@linux-m68k.org>
+Link: https://lore.kernel.org/r/99dc7d1f4c825621b5b120963a69f6cd3e9ca659.1723001788.git.fthain@linux-m68k.org
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/NCR5380.c | 78 +++++++++++++++++++++---------------------
+ 1 file changed, 39 insertions(+), 39 deletions(-)
+
+diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
+index 98b1a98db90f6..e8e0bd231df30 100644
+--- a/drivers/scsi/NCR5380.c
++++ b/drivers/scsi/NCR5380.c
+@@ -1485,6 +1485,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
+ unsigned char **data)
+ {
+ struct NCR5380_hostdata *hostdata = shost_priv(instance);
++ struct NCR5380_cmd *ncmd = NCR5380_to_ncmd(hostdata->connected);
+ int c = *count;
+ unsigned char p = *phase;
+ unsigned char *d = *data;
+@@ -1496,7 +1497,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
+ return -1;
+ }
+
+- NCR5380_to_ncmd(hostdata->connected)->phase = p;
++ ncmd->phase = p;
+
+ if (p & SR_IO) {
+ if (hostdata->read_overruns)
+@@ -1608,45 +1609,44 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
+ * request.
+ */
+
+- if (hostdata->flags & FLAG_DMA_FIXUP) {
+- if (p & SR_IO) {
+- /*
+- * The workaround was to transfer fewer bytes than we
+- * intended to with the pseudo-DMA read function, wait for
+- * the chip to latch the last byte, read it, and then disable
+- * pseudo-DMA mode.
+- *
+- * After REQ is asserted, the NCR5380 asserts DRQ and ACK.
+- * REQ is deasserted when ACK is asserted, and not reasserted
+- * until ACK goes false. Since the NCR5380 won't lower ACK
+- * until DACK is asserted, which won't happen unless we twiddle
+- * the DMA port or we take the NCR5380 out of DMA mode, we
+- * can guarantee that we won't handshake another extra
+- * byte.
+- */
+-
+- if (NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
+- BASR_DRQ, BASR_DRQ, 0) < 0) {
+- result = -1;
+- shost_printk(KERN_ERR, instance, "PDMA read: DRQ timeout\n");
+- }
+- if (NCR5380_poll_politely(hostdata, STATUS_REG,
+- SR_REQ, 0, 0) < 0) {
+- result = -1;
+- shost_printk(KERN_ERR, instance, "PDMA read: !REQ timeout\n");
+- }
+- d[*count - 1] = NCR5380_read(INPUT_DATA_REG);
+- } else {
+- /*
+- * Wait for the last byte to be sent. If REQ is being asserted for
+- * the byte we're interested, we'll ACK it and it will go false.
+- */
+- if (NCR5380_poll_politely2(hostdata,
+- BUS_AND_STATUS_REG, BASR_DRQ, BASR_DRQ,
+- BUS_AND_STATUS_REG, BASR_PHASE_MATCH, 0, 0) < 0) {
+- result = -1;
+- shost_printk(KERN_ERR, instance, "PDMA write: DRQ and phase timeout\n");
++ if ((hostdata->flags & FLAG_DMA_FIXUP) &&
++ (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)) {
++ /*
++ * The workaround was to transfer fewer bytes than we
++ * intended to with the pseudo-DMA receive function, wait for
++ * the chip to latch the last byte, read it, and then disable
++ * DMA mode.
++ *
++ * After REQ is asserted, the NCR5380 asserts DRQ and ACK.
++ * REQ is deasserted when ACK is asserted, and not reasserted
++ * until ACK goes false. Since the NCR5380 won't lower ACK
++ * until DACK is asserted, which won't happen unless we twiddle
++ * the DMA port or we take the NCR5380 out of DMA mode, we
++ * can guarantee that we won't handshake another extra
++ * byte.
++ *
++ * If sending, wait for the last byte to be sent. If REQ is
++ * being asserted for the byte we're interested, we'll ACK it
++ * and it will go false.
++ */
++ if (!NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
++ BASR_DRQ, BASR_DRQ, 0)) {
++ if ((p & SR_IO) &&
++ (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)) {
++ if (!NCR5380_poll_politely(hostdata, STATUS_REG,
++ SR_REQ, 0, 0)) {
++ d[c] = NCR5380_read(INPUT_DATA_REG);
++ --ncmd->this_residual;
++ } else {
++ result = -1;
++ scmd_printk(KERN_ERR, hostdata->connected,
++ "PDMA fixup: !REQ timeout\n");
++ }
+ }
++ } else if (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH) {
++ result = -1;
++ scmd_printk(KERN_ERR, hostdata->connected,
++ "PDMA fixup: DRQ timeout\n");
+ }
+ }
+
+--
+2.43.0
+
--- /dev/null
+From f350f955edcf27906beaefdb378d950241da86dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Jul 2024 02:24:20 -0700
+Subject: selftests/bpf: Fix C++ compile error from missing _Bool type
+
+From: Tony Ambardar <tony.ambardar@gmail.com>
+
+[ Upstream commit aa95073fd290b5b3e45f067fa22bb25e59e1ff7c ]
+
+While building, bpftool makes a skeleton from test_core_extern.c, which
+itself includes <stdbool.h> and uses the 'bool' type. However, the skeleton
+test_core_extern.skel.h generated *does not* include <stdbool.h> or use the
+'bool' type, instead using the C-only '_Bool' type. Compiling test_cpp.cpp
+with g++ 12.3 for mips64el/musl-libc then fails with error:
+
+ In file included from test_cpp.cpp:9:
+ test_core_extern.skel.h:45:17: error: '_Bool' does not name a type
+ 45 | _Bool CONFIG_BOOL;
+ | ^~~~~
+
+This was likely missed previously because glibc uses a GNU extension for
+<stdbool.h> with C++ (#define _Bool bool), not supported by musl libc.
+
+Normally, a C fragment would include <stdbool.h> and use the 'bool' type,
+and thus cleanly work after import by C++. The ideal fix would be for
+'bpftool gen skeleton' to output the correct type/include supporting C++,
+but in the meantime add a conditional define as above.
+
+Fixes: 7c8dce4b1661 ("bpftool: Make skeleton C code compilable with C++ compiler")
+Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/6fc1dd28b8bda49e51e4f610bdc9d22f4455632d.1722244708.git.tony.ambardar@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/test_cpp.cpp | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/tools/testing/selftests/bpf/test_cpp.cpp b/tools/testing/selftests/bpf/test_cpp.cpp
+index a8d2e9a87fbfa..6edcb541cc90e 100644
+--- a/tools/testing/selftests/bpf/test_cpp.cpp
++++ b/tools/testing/selftests/bpf/test_cpp.cpp
+@@ -3,6 +3,10 @@
+ #include <bpf/libbpf.h>
+ #include <bpf/bpf.h>
+ #include <bpf/btf.h>
++
++#ifndef _Bool
++#define _Bool bool
++#endif
+ #include "test_core_extern.skel.h"
+
+ /* do nothing, just make sure we can link successfully */
+--
+2.43.0
+
--- /dev/null
+From b42440cfb51d176cab7bb05d7f7618a1ed17e67b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jul 2024 22:54:29 -0700
+Subject: selftests/bpf: Fix compile error from rlim_t in sk_storage_map.c
+
+From: Tony Ambardar <tony.ambardar@gmail.com>
+
+[ Upstream commit d393f9479d4aaab0fa4c3caf513f28685e831f13 ]
+
+Cast 'rlim_t' argument to match expected type of printf() format and avoid
+compile errors seen building for mips64el/musl-libc:
+
+ In file included from map_tests/sk_storage_map.c:20:
+ map_tests/sk_storage_map.c: In function 'test_sk_storage_map_stress_free':
+ map_tests/sk_storage_map.c:414:56: error: format '%lu' expects argument of type 'long unsigned int', but argument 2 has type 'rlim_t' {aka 'long long unsigned int'} [-Werror=format=]
+ 414 | CHECK(err, "setrlimit(RLIMIT_NOFILE)", "rlim_new:%lu errno:%d",
+ | ^~~~~~~~~~~~~~~~~~~~~~~
+ 415 | rlim_new.rlim_cur, errno);
+ | ~~~~~~~~~~~~~~~~~
+ | |
+ | rlim_t {aka long long unsigned int}
+ ./test_maps.h:12:24: note: in definition of macro 'CHECK'
+ 12 | printf(format); \
+ | ^~~~~~
+ map_tests/sk_storage_map.c:414:68: note: format string is defined here
+ 414 | CHECK(err, "setrlimit(RLIMIT_NOFILE)", "rlim_new:%lu errno:%d",
+ | ~~^
+ | |
+ | long unsigned int
+ | %llu
+ cc1: all warnings being treated as errors
+
+Fixes: 51a0e301a563 ("bpf: Add BPF_MAP_TYPE_SK_STORAGE test to test_maps")
+Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/1e00a1fa7acf91b4ca135c4102dc796d518bad86.1721713597.git.tony.ambardar@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/map_tests/sk_storage_map.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/bpf/map_tests/sk_storage_map.c b/tools/testing/selftests/bpf/map_tests/sk_storage_map.c
+index e569edc679d88..9228e33cc0db7 100644
+--- a/tools/testing/selftests/bpf/map_tests/sk_storage_map.c
++++ b/tools/testing/selftests/bpf/map_tests/sk_storage_map.c
+@@ -416,7 +416,7 @@ static void test_sk_storage_map_stress_free(void)
+ rlim_new.rlim_max = rlim_new.rlim_cur + 128;
+ err = setrlimit(RLIMIT_NOFILE, &rlim_new);
+ CHECK(err, "setrlimit(RLIMIT_NOFILE)", "rlim_new:%lu errno:%d",
+- rlim_new.rlim_cur, errno);
++ (unsigned long) rlim_new.rlim_cur, errno);
+ }
+
+ err = do_sk_storage_map_stress_free();
+--
+2.43.0
+
--- /dev/null
+From 742f7636c72791cdba794f55a4512c4690a17b70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jul 2024 22:54:42 -0700
+Subject: selftests/bpf: Fix compiling core_reloc.c with musl-libc
+
+From: Tony Ambardar <tony.ambardar@gmail.com>
+
+[ Upstream commit debfa4f628f271f72933bf38d581cc53cfe1def5 ]
+
+The type 'loff_t' is a GNU extension and not exposed by the musl 'fcntl.h'
+header unless _GNU_SOURCE is defined. Add this definition to fix errors
+seen compiling for mips64el/musl-libc:
+
+ In file included from tools/testing/selftests/bpf/prog_tests/core_reloc.c:4:
+ ./bpf_testmod/bpf_testmod.h:10:9: error: unknown type name 'loff_t'
+ 10 | loff_t off;
+ | ^~~~~~
+ ./bpf_testmod/bpf_testmod.h:16:9: error: unknown type name 'loff_t'
+ 16 | loff_t off;
+ | ^~~~~~
+
+Fixes: 6bcd39d366b6 ("selftests/bpf: Add CO-RE relocs selftest relying on kernel module BTF")
+Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/11c3af75a7eb6bcb7ad9acfae6a6f470c572eb82.1721713597.git.tony.ambardar@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/core_reloc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/core_reloc.c b/tools/testing/selftests/bpf/prog_tests/core_reloc.c
+index 4739b15b2a979..ae2c7e8fb6600 100644
+--- a/tools/testing/selftests/bpf/prog_tests/core_reloc.c
++++ b/tools/testing/selftests/bpf/prog_tests/core_reloc.c
+@@ -1,4 +1,5 @@
+ // SPDX-License-Identifier: GPL-2.0
++#define _GNU_SOURCE
+ #include <test_progs.h>
+ #include "progs/core_reloc_types.h"
+ #include "bpf_testmod/bpf_testmod.h"
+--
+2.43.0
+
--- /dev/null
+From db3976e83506c974ad502015af55f742dbddbf28 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jul 2024 22:54:40 -0700
+Subject: selftests/bpf: Fix compiling flow_dissector.c with musl-libc
+
+From: Tony Ambardar <tony.ambardar@gmail.com>
+
+[ Upstream commit 5e4c43bcb85973243d7274e0058b6e8f5810e4f7 ]
+
+The GNU version of 'struct tcphdr' has members 'doff', 'source' and 'dest',
+which are not exposed by musl libc headers unless _GNU_SOURCE is defined.
+
+Add this definition to fix errors seen compiling for mips64el/musl-libc:
+
+ flow_dissector.c:118:30: error: 'struct tcphdr' has no member named 'doff'
+ 118 | .tcp.doff = 5,
+ | ^~~~
+ flow_dissector.c:119:30: error: 'struct tcphdr' has no member named 'source'
+ 119 | .tcp.source = 80,
+ | ^~~~~~
+ flow_dissector.c:120:30: error: 'struct tcphdr' has no member named 'dest'
+ 120 | .tcp.dest = 8080,
+ | ^~~~
+
+Fixes: ae173a915785 ("selftests/bpf: support BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG")
+Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/8f7ab21a73f678f9cebd32b26c444a686e57414d.1721713597.git.tony.ambardar@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/flow_dissector.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c
+index 225714f71ac6e..334449262beff 100644
+--- a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c
++++ b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c
+@@ -1,4 +1,5 @@
+ // SPDX-License-Identifier: GPL-2.0
++#define _GNU_SOURCE
+ #include <test_progs.h>
+ #include <network_helpers.h>
+ #include <error.h>
+--
+2.43.0
+
--- /dev/null
+From 7f15d61187328002de593ebf4e84b63a92b03093 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jul 2024 22:54:39 -0700
+Subject: selftests/bpf: Fix compiling kfree_skb.c with musl-libc
+
+From: Tony Ambardar <tony.ambardar@gmail.com>
+
+[ Upstream commit bae9a5ce7d3a9b3a9e07b31ab9e9c58450e3e9fd ]
+
+The GNU version of 'struct tcphdr' with member 'doff' is not exposed by
+musl headers unless _GNU_SOURCE is defined. Add this definition to fix
+errors seen compiling for mips64el/musl-libc:
+
+ In file included from kfree_skb.c:2:
+ kfree_skb.c: In function 'on_sample':
+ kfree_skb.c:45:30: error: 'struct tcphdr' has no member named 'doff'
+ 45 | if (CHECK(pkt_v6->tcp.doff != 5, "check_tcp",
+ | ^
+
+Fixes: 580d656d80cf ("selftests/bpf: Add kfree_skb raw_tp test")
+Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/e2d8cedc790959c10d6822a51f01a7a3616bea1b.1721713597.git.tony.ambardar@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/kfree_skb.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/kfree_skb.c b/tools/testing/selftests/bpf/prog_tests/kfree_skb.c
+index ddfb6bf971524..f1a7d1fa0ee91 100644
+--- a/tools/testing/selftests/bpf/prog_tests/kfree_skb.c
++++ b/tools/testing/selftests/bpf/prog_tests/kfree_skb.c
+@@ -1,4 +1,5 @@
+ // SPDX-License-Identifier: GPL-2.0
++#define _GNU_SOURCE
+ #include <test_progs.h>
+ #include <network_helpers.h>
+
+--
+2.43.0
+
--- /dev/null
+From 82dd0d87bc905b96df6346df67e0754aa09809bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jul 2024 22:54:41 -0700
+Subject: selftests/bpf: Fix compiling tcp_rtt.c with musl-libc
+
+From: Tony Ambardar <tony.ambardar@gmail.com>
+
+[ Upstream commit 18826fb0b79c3c3cd1fe765d85f9c6f1a902c722 ]
+
+The GNU version of 'struct tcp_info' in 'netinet/tcp.h' is not exposed by
+musl headers unless _GNU_SOURCE is defined.
+
+Add this definition to fix errors seen compiling for mips64el/musl-libc:
+
+ tcp_rtt.c: In function 'wait_for_ack':
+ tcp_rtt.c:24:25: error: storage size of 'info' isn't known
+ 24 | struct tcp_info info;
+ | ^~~~
+ tcp_rtt.c:24:25: error: unused variable 'info' [-Werror=unused-variable]
+ cc1: all warnings being treated as errors
+
+Fixes: 1f4f80fed217 ("selftests/bpf: test_progs: convert test_tcp_rtt")
+Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/f2329767b15df206f08a5776d35a47c37da855ae.1721713597.git.tony.ambardar@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/tcp_rtt.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c b/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c
+index d207e968e6b1b..dee68ef976ae9 100644
+--- a/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c
++++ b/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c
+@@ -1,4 +1,5 @@
+ // SPDX-License-Identifier: GPL-2.0
++#define _GNU_SOURCE
+ #include <test_progs.h>
+ #include "cgroup_helpers.h"
+ #include "network_helpers.h"
+--
+2.43.0
+
--- /dev/null
+From 65332b4eae55069dbf24951d841db9acb8066dd7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jul 2024 22:54:30 -0700
+Subject: selftests/bpf: Fix error compiling bpf_iter_setsockopt.c with musl
+ libc
+
+From: Tony Ambardar <tony.ambardar@gmail.com>
+
+[ Upstream commit 7b10f0c227ce3fa055d601f058dc411092a62a78 ]
+
+Existing code calls getsockname() with a 'struct sockaddr_in6 *' argument
+where a 'struct sockaddr *' argument is declared, yielding compile errors
+when building for mips64el/musl-libc:
+
+ bpf_iter_setsockopt.c: In function 'get_local_port':
+ bpf_iter_setsockopt.c:98:30: error: passing argument 2 of 'getsockname' from incompatible pointer type [-Werror=incompatible-pointer-types]
+ 98 | if (!getsockname(fd, &addr, &addrlen))
+ | ^~~~~
+ | |
+ | struct sockaddr_in6 *
+ In file included from .../netinet/in.h:10,
+ from .../arpa/inet.h:9,
+ from ./test_progs.h:17,
+ from bpf_iter_setsockopt.c:5:
+ .../sys/socket.h:391:23: note: expected 'struct sockaddr * restrict' but argument is of type 'struct sockaddr_in6 *'
+ 391 | int getsockname (int, struct sockaddr *__restrict, socklen_t *__restrict);
+ | ^
+ cc1: all warnings being treated as errors
+
+This compiled under glibc only because the argument is declared to be a
+"funky" transparent union which includes both types above. Explicitly cast
+the argument to allow compiling for both musl and glibc.
+
+Fixes: eed92afdd14c ("bpf: selftest: Test batching and bpf_(get|set)sockopt in bpf tcp iter")
+Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Geliang Tang <geliang@kernel.org>
+Link: https://lore.kernel.org/bpf/f41def0f17b27a23b1709080e4e3f37f4cc11ca9.1721713597.git.tony.ambardar@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/bpf_iter_setsockopt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_iter_setsockopt.c b/tools/testing/selftests/bpf/prog_tests/bpf_iter_setsockopt.c
+index 85babb0487b31..59a9b6e02452a 100644
+--- a/tools/testing/selftests/bpf/prog_tests/bpf_iter_setsockopt.c
++++ b/tools/testing/selftests/bpf/prog_tests/bpf_iter_setsockopt.c
+@@ -95,7 +95,7 @@ static unsigned short get_local_port(int fd)
+ struct sockaddr_in6 addr;
+ socklen_t addrlen = sizeof(addr);
+
+- if (!getsockname(fd, &addr, &addrlen))
++ if (!getsockname(fd, (struct sockaddr *)&addr, &addrlen))
+ return ntohs(addr.sin6_port);
+
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From 70bc34eddf605ea0e7e0cfb1d48310abda0d2f3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Jul 2024 02:24:19 -0700
+Subject: selftests/bpf: Fix error compiling test_lru_map.c
+
+From: Tony Ambardar <tony.ambardar@gmail.com>
+
+[ Upstream commit cacf2a5a78cd1f5f616eae043ebc6f024104b721 ]
+
+Although the post-increment in macro 'CPU_SET(next++, &cpuset)' seems safe,
+the sequencing can raise compile errors, so move the increment outside the
+macro. This avoids an error seen using gcc 12.3.0 for mips64el/musl-libc:
+
+ In file included from test_lru_map.c:11:
+ test_lru_map.c: In function 'sched_next_online':
+ test_lru_map.c:129:29: error: operation on 'next' may be undefined [-Werror=sequence-point]
+ 129 | CPU_SET(next++, &cpuset);
+ | ^
+ cc1: all warnings being treated as errors
+
+Fixes: 3fbfadce6012 ("bpf: Fix test_lru_sanity5() in test_lru_map.c")
+Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/22993dfb11ccf27925a626b32672fd3324cb76c4.1722244708.git.tony.ambardar@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/test_lru_map.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/bpf/test_lru_map.c b/tools/testing/selftests/bpf/test_lru_map.c
+index 7e9049fa3edfe..1359de58da6c5 100644
+--- a/tools/testing/selftests/bpf/test_lru_map.c
++++ b/tools/testing/selftests/bpf/test_lru_map.c
+@@ -137,7 +137,8 @@ static int sched_next_online(int pid, int *next_to_try)
+
+ while (next < nr_cpus) {
+ CPU_ZERO(&cpuset);
+- CPU_SET(next++, &cpuset);
++ CPU_SET(next, &cpuset);
++ next++;
+ if (!sched_setaffinity(pid, sizeof(cpuset), &cpuset)) {
+ ret = 0;
+ break;
+--
+2.43.0
+
--- /dev/null
+From e6857eed4b42539680a49494f738fc8e8164c60e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jul 2024 22:54:46 -0700
+Subject: selftests/bpf: Fix errors compiling cg_storage_multi.h with musl libc
+
+From: Tony Ambardar <tony.ambardar@gmail.com>
+
+[ Upstream commit 730561d3c08d4a327cceaabf11365958a1c00cec ]
+
+Remove a redundant include of '<asm/types.h>', whose needed definitions are
+already included (via '<linux/types.h>') in cg_storage_multi_egress_only.c,
+cg_storage_multi_isolated.c, and cg_storage_multi_shared.c. This avoids
+redefinition errors seen compiling for mips64el/musl-libc like:
+
+ In file included from progs/cg_storage_multi_egress_only.c:13:
+ In file included from progs/cg_storage_multi.h:6:
+ In file included from /usr/mips64el-linux-gnuabi64/include/asm/types.h:23:
+ /usr/include/asm-generic/int-l64.h:29:25: error: typedef redefinition with different types ('long' vs 'long long')
+ 29 | typedef __signed__ long __s64;
+ | ^
+ /usr/include/asm-generic/int-ll64.h:30:44: note: previous definition is here
+ 30 | __extension__ typedef __signed__ long long __s64;
+ | ^
+
+Fixes: 9e5bd1f7633b ("selftests/bpf: Test CGROUP_STORAGE map can't be used by multiple progs")
+Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/4f4702e9f6115b7f84fea01b2326ca24c6df7ba8.1721713597.git.tony.ambardar@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/progs/cg_storage_multi.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/progs/cg_storage_multi.h b/tools/testing/selftests/bpf/progs/cg_storage_multi.h
+index a0778fe7857a1..41d59f0ee606c 100644
+--- a/tools/testing/selftests/bpf/progs/cg_storage_multi.h
++++ b/tools/testing/selftests/bpf/progs/cg_storage_multi.h
+@@ -3,8 +3,6 @@
+ #ifndef __PROGS_CG_STORAGE_MULTI_H
+ #define __PROGS_CG_STORAGE_MULTI_H
+
+-#include <asm/types.h>
+-
+ struct cgroup_value {
+ __u32 egress_pkts;
+ __u32 ingress_pkts;
+--
+2.43.0
+
--- /dev/null
+From e41ca010ff45755570bafa4858a97c35247b7280 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jul 2024 22:54:34 -0700
+Subject: selftests/bpf: Fix missing ARRAY_SIZE() definition in bench.c
+
+From: Tony Ambardar <tony.ambardar@gmail.com>
+
+[ Upstream commit d44c93fc2f5a0c47b23fa03d374e45259abd92d2 ]
+
+Add a "bpf_util.h" include to avoid the following error seen compiling for
+mips64el with musl libc:
+
+ bench.c: In function 'find_benchmark':
+ bench.c:590:25: error: implicit declaration of function 'ARRAY_SIZE' [-Werror=implicit-function-declaration]
+ 590 | for (i = 0; i < ARRAY_SIZE(benchs); i++) {
+ | ^~~~~~~~~~
+ cc1: all warnings being treated as errors
+
+Fixes: 8e7c2a023ac0 ("selftests/bpf: Add benchmark runner infrastructure")
+Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/bc4dde77dfcd17a825d8f28f72f3292341966810.1721713597.git.tony.ambardar@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/bench.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/testing/selftests/bpf/bench.c b/tools/testing/selftests/bpf/bench.c
+index 6ea15b93a2f8a..74dad15a74693 100644
+--- a/tools/testing/selftests/bpf/bench.c
++++ b/tools/testing/selftests/bpf/bench.c
+@@ -11,6 +11,7 @@
+ #include <sys/resource.h>
+ #include <signal.h>
+ #include "bench.h"
++#include "bpf_util.h"
+ #include "testing_helpers.h"
+
+ struct env env = {
+--
+2.43.0
+
--- /dev/null
+From 6aefdfbbfc231cda9dd43bbc770af702cc747e55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Sep 2024 10:50:14 +0200
+Subject: selftests: vDSO: fix ELF hash table entry size for s390x
+
+From: Jens Remus <jremus@linux.ibm.com>
+
+[ Upstream commit 14be4e6f35221c4731b004553ecf7cbc6dc1d2d8 ]
+
+The vDSO self tests fail on s390x for a vDSO linked with the GNU linker
+ld as follows:
+
+ # ./vdso_test_gettimeofday
+ Floating point exception (core dumped)
+
+On s390x the ELF hash table entries are 64 bits instead of 32 bits in
+size (see Glibc sysdeps/unix/sysv/linux/s390/bits/elfclass.h).
+
+Fixes: 40723419f407 ("kselftest: Enable vDSO test on non x86 platforms")
+Reported-by: Heiko Carstens <hca@linux.ibm.com>
+Tested-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Jens Remus <jremus@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/vDSO/parse_vdso.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/tools/testing/selftests/vDSO/parse_vdso.c b/tools/testing/selftests/vDSO/parse_vdso.c
+index d9ccc5acac182..7dd5668ea8a6e 100644
+--- a/tools/testing/selftests/vDSO/parse_vdso.c
++++ b/tools/testing/selftests/vDSO/parse_vdso.c
+@@ -36,6 +36,12 @@
+ #define ELF_BITS_XFORM(bits, x) ELF_BITS_XFORM2(bits, x)
+ #define ELF(x) ELF_BITS_XFORM(ELF_BITS, x)
+
++#ifdef __s390x__
++#define ELF_HASH_ENTRY ELF(Xword)
++#else
++#define ELF_HASH_ENTRY ELF(Word)
++#endif
++
+ static struct vdso_info
+ {
+ bool valid;
+@@ -47,8 +53,8 @@ static struct vdso_info
+ /* Symbol table */
+ ELF(Sym) *symtab;
+ const char *symstrings;
+- ELF(Word) *bucket, *chain;
+- ELF(Word) nbucket, nchain;
++ ELF_HASH_ENTRY *bucket, *chain;
++ ELF_HASH_ENTRY nbucket, nchain;
+
+ /* Version table */
+ ELF(Versym) *versym;
+@@ -115,7 +121,7 @@ void vdso_init_from_sysinfo_ehdr(uintptr_t base)
+ /*
+ * Fish out the useful bits of the dynamic table.
+ */
+- ELF(Word) *hash = 0;
++ ELF_HASH_ENTRY *hash = 0;
+ vdso_info.symstrings = 0;
+ vdso_info.symtab = 0;
+ vdso_info.versym = 0;
+@@ -133,7 +139,7 @@ void vdso_init_from_sysinfo_ehdr(uintptr_t base)
+ + vdso_info.load_offset);
+ break;
+ case DT_HASH:
+- hash = (ELF(Word) *)
++ hash = (ELF_HASH_ENTRY *)
+ ((uintptr_t)dyn[i].d_un.d_ptr
+ + vdso_info.load_offset);
+ break;
+--
+2.43.0
+
--- /dev/null
+From a06343ed71e9bc7998204cfd27db2fe9c0380db5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Aug 2024 14:28:35 +0200
+Subject: selftests: vDSO: fix vDSO name for powerpc
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 59eb856c3ed9b3552befd240c0c339f22eed3fa1 ]
+
+Following error occurs when running vdso_test_correctness on powerpc:
+
+~ # ./vdso_test_correctness
+[WARN] failed to find vDSO
+[SKIP] No vDSO, so skipping clock_gettime() tests
+[SKIP] No vDSO, so skipping clock_gettime64() tests
+[RUN] Testing getcpu...
+[OK] CPU 0: syscall: cpu 0, node 0
+
+On powerpc, vDSO is neither called linux-vdso.so.1 nor linux-gate.so.1
+but linux-vdso32.so.1 or linux-vdso64.so.1.
+
+Also search those two names before giving up.
+
+Fixes: c7e5789b24d3 ("kselftest: Move test_vdso to the vDSO test suite")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Acked-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/vDSO/vdso_test_correctness.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/tools/testing/selftests/vDSO/vdso_test_correctness.c b/tools/testing/selftests/vDSO/vdso_test_correctness.c
+index c4aea794725a7..739cd83f3dfb7 100644
+--- a/tools/testing/selftests/vDSO/vdso_test_correctness.c
++++ b/tools/testing/selftests/vDSO/vdso_test_correctness.c
+@@ -113,6 +113,12 @@ static void fill_function_pointers()
+ if (!vdso)
+ vdso = dlopen("linux-gate.so.1",
+ RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
++ if (!vdso)
++ vdso = dlopen("linux-vdso32.so.1",
++ RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
++ if (!vdso)
++ vdso = dlopen("linux-vdso64.so.1",
++ RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
+ if (!vdso) {
+ printf("[WARN]\tfailed to find vDSO\n");
+ return;
+--
+2.43.0
+
--- /dev/null
+From d6be3b87b8f4fd69c72adfaed50f40fcc3e2c9e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Aug 2024 14:28:37 +0200
+Subject: selftests: vDSO: fix vDSO symbols lookup for powerpc64
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit ba83b3239e657469709d15dcea5f9b65bf9dbf34 ]
+
+On powerpc64, following tests fail locating vDSO functions:
+
+ ~ # ./vdso_test_abi
+ TAP version 13
+ 1..16
+ # [vDSO kselftest] VDSO_VERSION: LINUX_2.6.15
+ # Couldn't find __kernel_gettimeofday
+ ok 1 # SKIP __kernel_gettimeofday
+ # clock_id: CLOCK_REALTIME
+ # Couldn't find __kernel_clock_gettime
+ ok 2 # SKIP __kernel_clock_gettime CLOCK_REALTIME
+ # Couldn't find __kernel_clock_getres
+ ok 3 # SKIP __kernel_clock_getres CLOCK_REALTIME
+ ...
+ # Couldn't find __kernel_time
+ ok 16 # SKIP __kernel_time
+ # Totals: pass:0 fail:0 xfail:0 xpass:0 skip:16 error:0
+
+ ~ # ./vdso_test_getrandom
+ __kernel_getrandom is missing!
+
+ ~ # ./vdso_test_gettimeofday
+ Could not find __kernel_gettimeofday
+
+ ~ # ./vdso_test_getcpu
+ Could not find __kernel_getcpu
+
+On powerpc64, as shown below by readelf, vDSO functions symbols have
+type NOTYPE, so also accept that type when looking for symbols.
+
+$ powerpc64-linux-gnu-readelf -a arch/powerpc/kernel/vdso/vdso64.so.dbg
+ELF Header:
+ Magic: 7f 45 4c 46 02 02 01 00 00 00 00 00 00 00 00 00
+ Class: ELF64
+ Data: 2's complement, big endian
+ Version: 1 (current)
+ OS/ABI: UNIX - System V
+ ABI Version: 0
+ Type: DYN (Shared object file)
+ Machine: PowerPC64
+ Version: 0x1
+...
+
+Symbol table '.dynsym' contains 12 entries:
+ Num: Value Size Type Bind Vis Ndx Name
+ 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+ 1: 0000000000000524 84 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
+ 2: 00000000000005f0 36 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
+ 3: 0000000000000578 68 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
+ 4: 0000000000000000 0 OBJECT GLOBAL DEFAULT ABS LINUX_2.6.15
+ 5: 00000000000006c0 48 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
+ 6: 0000000000000614 172 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
+ 7: 00000000000006f0 84 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
+ 8: 000000000000047c 84 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
+ 9: 0000000000000454 12 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
+ 10: 00000000000004d0 84 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
+ 11: 00000000000005bc 52 NOTYPE GLOBAL DEFAULT 8 __[...]@@LINUX_2.6.15
+
+Symbol table '.symtab' contains 56 entries:
+ Num: Value Size Type Bind Vis Ndx Name
+...
+ 45: 0000000000000000 0 OBJECT GLOBAL DEFAULT ABS LINUX_2.6.15
+ 46: 00000000000006c0 48 NOTYPE GLOBAL DEFAULT 8 __kernel_getcpu
+ 47: 0000000000000524 84 NOTYPE GLOBAL DEFAULT 8 __kernel_clock_getres
+ 48: 00000000000005f0 36 NOTYPE GLOBAL DEFAULT 8 __kernel_get_tbfreq
+ 49: 000000000000047c 84 NOTYPE GLOBAL DEFAULT 8 __kernel_gettimeofday
+ 50: 0000000000000614 172 NOTYPE GLOBAL DEFAULT 8 __kernel_sync_dicache
+ 51: 00000000000006f0 84 NOTYPE GLOBAL DEFAULT 8 __kernel_getrandom
+ 52: 0000000000000454 12 NOTYPE GLOBAL DEFAULT 8 __kernel_sigtram[...]
+ 53: 0000000000000578 68 NOTYPE GLOBAL DEFAULT 8 __kernel_time
+ 54: 00000000000004d0 84 NOTYPE GLOBAL DEFAULT 8 __kernel_clock_g[...]
+ 55: 00000000000005bc 52 NOTYPE GLOBAL DEFAULT 8 __kernel_get_sys[...]
+
+Fixes: 98eedc3a9dbf ("Document the vDSO and add a reference parser")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Acked-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/vDSO/parse_vdso.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/vDSO/parse_vdso.c b/tools/testing/selftests/vDSO/parse_vdso.c
+index 4ae417372e9eb..d9ccc5acac182 100644
+--- a/tools/testing/selftests/vDSO/parse_vdso.c
++++ b/tools/testing/selftests/vDSO/parse_vdso.c
+@@ -216,7 +216,8 @@ void *vdso_sym(const char *version, const char *name)
+ ELF(Sym) *sym = &vdso_info.symtab[chain];
+
+ /* Check for a defined global or weak function w/ right name. */
+- if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC)
++ if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC &&
++ ELF64_ST_TYPE(sym->st_info) != STT_NOTYPE)
+ continue;
+ if (ELF64_ST_BIND(sym->st_info) != STB_GLOBAL &&
+ ELF64_ST_BIND(sym->st_info) != STB_WEAK)
+--
+2.43.0
+
--- /dev/null
+From 407d64571e13a6334233584504fec13509eb7e00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Aug 2024 14:28:36 +0200
+Subject: selftests: vDSO: fix vdso_config for powerpc
+
+From: Christophe Leroy <christophe.leroy@csgroup.eu>
+
+[ Upstream commit 7d297c419b08eafa69ce27243ee9bbecab4fcaa4 ]
+
+Running vdso_test_correctness on powerpc64 gives the following warning:
+
+ ~ # ./vdso_test_correctness
+ Warning: failed to find clock_gettime64 in vDSO
+
+This is because vdso_test_correctness was built with VDSO_32BIT defined.
+
+__powerpc__ macro is defined on both powerpc32 and powerpc64 so
+__powerpc64__ needs to be checked first in vdso_config.h
+
+Fixes: 693f5ca08ca0 ("kselftest: Extend vDSO selftest")
+Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Acked-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/vDSO/vdso_config.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/tools/testing/selftests/vDSO/vdso_config.h b/tools/testing/selftests/vDSO/vdso_config.h
+index 6188b16827d1d..446eb9737273b 100644
+--- a/tools/testing/selftests/vDSO/vdso_config.h
++++ b/tools/testing/selftests/vDSO/vdso_config.h
+@@ -18,13 +18,13 @@
+ #elif defined(__aarch64__)
+ #define VDSO_VERSION 3
+ #define VDSO_NAMES 0
+-#elif defined(__powerpc__)
++#elif defined(__powerpc64__)
+ #define VDSO_VERSION 1
+ #define VDSO_NAMES 0
+-#define VDSO_32BIT 1
+-#elif defined(__powerpc64__)
++#elif defined(__powerpc__)
+ #define VDSO_VERSION 1
+ #define VDSO_NAMES 0
++#define VDSO_32BIT 1
+ #elif defined (__s390__)
+ #define VDSO_VERSION 2
+ #define VDSO_NAMES 0
+--
+2.43.0
+
--- /dev/null
+From a90697001256a9051200004183d456ff9f555448 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Sep 2024 10:50:15 +0200
+Subject: selftests: vDSO: fix vdso_config for s390
+
+From: Heiko Carstens <hca@linux.ibm.com>
+
+[ Upstream commit a6e23fb8d3c0e3904da70beaf5d7e840a983c97f ]
+
+Running vdso_test_correctness on s390x (aka s390 64 bit) emits a warning:
+
+Warning: failed to find clock_gettime64 in vDSO
+
+This is caused by the "#elif defined (__s390__)" check in vdso_config.h
+which the defines VDSO_32BIT.
+
+If __s390x__ is defined also __s390__ is defined. Therefore the correct
+check must make sure that only __s390__ is defined.
+
+Therefore add the missing !defined(__s390x__). Also use common
+__s390x__ define instead of __s390X__.
+
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Fixes: 693f5ca08ca0 ("kselftest: Extend vDSO selftest")
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/vDSO/vdso_config.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/vDSO/vdso_config.h b/tools/testing/selftests/vDSO/vdso_config.h
+index 446eb9737273b..a6868ca0e4f89 100644
+--- a/tools/testing/selftests/vDSO/vdso_config.h
++++ b/tools/testing/selftests/vDSO/vdso_config.h
+@@ -25,11 +25,11 @@
+ #define VDSO_VERSION 1
+ #define VDSO_NAMES 0
+ #define VDSO_32BIT 1
+-#elif defined (__s390__)
++#elif defined (__s390__) && !defined(__s390x__)
+ #define VDSO_VERSION 2
+ #define VDSO_NAMES 0
+ #define VDSO_32BIT 1
+-#elif defined (__s390X__)
++#elif defined (__s390x__)
+ #define VDSO_VERSION 2
+ #define VDSO_NAMES 0
+ #elif defined(__mips__)
+--
+2.43.0
+
cgroup-move-rcu_head-up-near-the-top-of-cgroup_root.patch
usb-serial-pl2303-add-device-id-for-macrosilicon-ms3020.patch
usb-usbtmc-prevent-kernel-usb-infoleak.patch
+edac-synopsys-add-support-for-version-3-of-the-synop.patch
+edac-synopsys-use-the-correct-register-to-disable-th.patch
+edac-synopsys-re-enable-the-error-interrupts-on-v3-h.patch
+edac-synopsys-fix-ecc-status-and-irq-control-race-co.patch
+edac-synopsys-fix-error-injection-on-zynq-ultrascale.patch
+wifi-rtw88-always-wait-for-both-firmware-loading-att.patch
+crypto-xor-fix-template-benchmarking.patch
+acpi-pmic-remove-unneeded-check-in-tps68470_pmic_opr.patch
+wifi-ath9k-fix-parameter-check-in-ath9k_init_debug.patch
+wifi-ath9k-remove-error-checks-when-creating-debugfs.patch
+net-stmmac-dwmac-loongson-init-ref-and-ptp-clocks-ra.patch
+wifi-rtw88-remove-cpt-execution-branch-never-used.patch
+fs-explicitly-unregister-per-superblock-bdis.patch
+mount-warn-only-once-about-timestamp-range-expiratio.patch
+fs-namespace-fnic-switch-to-use-pttd.patch
+mount-handle-oom-on-mnt_warn_timestamp_expiry.patch
+wifi-iwlwifi-mvm-increase-the-time-between-ranging-m.patch
+padata-honor-the-caller-s-alignment-in-case-of-chunk.patch
+can-j1939-use-correct-function-name-in-comment.patch
+acpi-bus-avoid-using-cppc-if-not-supported-by-firmwa.patch
+acpi-cppc-fix-mask_val-usage.patch
+netfilter-nf_tables-elements-with-timeout-below-conf.patch
+netfilter-nf_tables-reject-element-expiration-with-n.patch
+netfilter-nf_tables-reject-expiration-higher-than-ti.patch
+netfilter-nf_tables-remove-annotation-to-access-set-.patch
+cpufreq-ti-cpufreq-introduce-quirks-to-handle-syscon.patch
+x86-sgx-fix-deadlock-in-sgx-numa-node-search.patch
+wifi-cfg80211-fix-ubsan-noise-in-cfg80211_wext_siwsc.patch
+wifi-mt76-mt7915-fix-rx-filter-setting-for-bfee-func.patch
+wifi-cfg80211-fix-two-more-possible-ubsan-detected-o.patch
+wifi-mac80211-use-two-phase-skb-reclamation-in-ieee8.patch
+wifi-wilc1000-fix-potential-rcu-dereference-issue-in.patch
+sock_map-add-a-cond_resched-in-sock_hash_free.patch
+can-bcm-clear-bo-bcm_proc_read-after-remove_proc_ent.patch
+can-m_can-m_can_close-stop-clocks-after-device-has-b.patch
+bluetooth-btusb-fix-not-handling-zpl-short-transfer.patch
+bareudp-pull-inner-ip-header-in-bareudp_udp_encap_re.patch
+net-geneve-support-ipv4-ipv6-as-inner-protocol.patch
+geneve-fix-incorrect-inner-network-header-offset-whe.patch
+bareudp-pull-inner-ip-header-on-xmit.patch
+net-enetc-use-irqf_no_autoen-flag-in-request_irq.patch
+r8169-disable-aldps-per-default-for-rtl8125.patch
+net-ipv6-rpl_iptunnel-fix-memory-leak-in-rpl_input.patch
+net-tipc-avoid-possible-garbage-value.patch
+block-bfq-fix-possible-uaf-for-bfqq-bic-with-merge-c.patch
+block-bfq-choose-the-last-bfqq-from-merge-chain-in-b.patch
+block-bfq-don-t-break-merge-chain-in-bfq_split_bfqq.patch
+block-print-symbolic-error-name-instead-of-error-cod.patch
+block-fix-potential-invalid-pointer-dereference-in-b.patch
+spi-ppc4xx-handle-irq_of_parse_and_map-errors.patch
+spi-ppc4xx-avoid-returning-0-when-failed-to-parse-an.patch
+arm64-dts-renesas-r9a07g044-correct-gicd-and-gicr-si.patch
+arm-dts-microchip-sam9x60-fix-rtc-rtt-clocks.patch
+arm-dts-imx7d-zii-rmu2-fix-ethernet-phy-pinctrl-prop.patch
+arm-versatile-fix-of-node-leak-in-cpus-prepare.patch
+reset-berlin-fix-of-node-leak-in-probe-error-path.patch
+reset-k210-fix-of-node-leak-in-probe-error-path.patch
+clocksource-drivers-qcom-add-missing-iounmap-on-erro.patch
+m68k-fix-kernel_clone_args.flags-in-m68k_clone.patch
+hwmon-max16065-fix-overflows-seen-when-writing-limit.patch
+i2c-add-i2c_get_match_data.patch
+hwmon-max16065-remove-use-of-i2c_match_id.patch
+hwmon-max16065-fix-alarm-attributes.patch
+mtd-slram-insert-break-after-errors-in-parsing-the-m.patch
+hwmon-ntc_thermistor-fix-module-autoloading.patch
+power-supply-axp20x_battery-remove-design-from-min-a.patch
+power-supply-max17042_battery-fix-soc-threshold-calc.patch
+fbdev-hpfb-fix-an-error-handling-path-in-hpfb_dio_pr.patch
+mtd-powernv-add-check-devm_kasprintf-returned-value.patch
+pmdomain-core-harden-inter-column-space-in-debug-sum.patch
+drm-stm-fix-an-error-handling-path-in-stm_drm_platfo.patch
+drm-amd-display-add-null-check-for-set_output_gamma-.patch
+drm-amdgpu-replace-one-element-array-with-flexible-a.patch
+drm-amdgpu-properly-handle-vbios-fake-edid-sizing.patch
+drm-radeon-replace-one-element-array-with-flexible-a.patch
+drm-radeon-properly-handle-vbios-fake-edid-sizing.patch
+scsi-ncr5380-add-scp-members-to-struct-ncr5380_cmd.patch
+scsi-ncr5380-check-for-phase-match-during-pdma-fixup.patch
+drm-rockchip-vop-allow-4096px-width-scaling.patch
+drm-rockchip-dw_hdmi-fix-reading-edid-when-using-a-f.patch
+drm-radeon-evergreen_cs-fix-int-overflow-errors-in-c.patch
+drm-bridge-lontium-lt8912b-validate-mode-in-drm_brid.patch
+scsi-elx-libefc-fix-potential-use-after-free-in-efc_.patch
+jfs-fix-out-of-bounds-in-dbnextag-and-dialloc.patch
+drm-mediatek-use-spin_lock_irqsave-for-crtc-event-lo.patch
+powerpc-32-remove-the-nobats-kernel-parameter.patch
+powerpc-32-remove-noltlbs-kernel-parameter.patch
+powerpc-8xx-fix-initial-memory-mapping.patch
+powerpc-8xx-fix-kernel-vs-user-address-comparison.patch
+selftests-vdso-fix-vdso-name-for-powerpc.patch
+selftests-vdso-fix-vdso_config-for-powerpc.patch
+selftests-vdso-fix-vdso-symbols-lookup-for-powerpc64.patch
+drm-msm-fix-incorrect-file-name-output-in-adreno_req.patch
+drm-msm-a5xx-disable-preemption-in-submits-by-defaul.patch
+drm-msm-a5xx-properly-clear-preemption-records-on-re.patch
+drm-msm-a5xx-fix-races-in-preemption-evaluation-stag.patch
+drm-msm-drop-priv-lastctx.patch
+drm-msm-a5xx-workaround-early-ring-buffer-emptiness-.patch
+ipmi-docs-don-t-advertise-deprecated-sysfs-entries.patch
+drm-msm-fix-s-null-argument-error.patch
+drivers-drm-exynos_drm_gsc-fix-wrong-assignment-in-g.patch
+xen-use-correct-end-address-of-kernel-for-conflict-c.patch
+mm-add-page_align_down-macro.patch
+minmax-avoid-overly-complex-min-max-macro-arguments-.patch
+xen-introduce-generic-helper-checking-for-memory-map.patch
+xen-move-max_pfn-in-xen_memory_setup-out-of-function.patch
+xen-add-capability-to-remap-non-ram-pages-to-differe.patch
+xen-tolerate-acpi-nvs-memory-overlapping-with-xen-al.patch
+selftests-vdso-fix-elf-hash-table-entry-size-for-s39.patch
+selftests-vdso-fix-vdso_config-for-s390.patch
+xen-swiotlb-add-alignment-check-for-dma-buffers.patch
+tpm-clean-up-tpm-space-after-command-failure.patch
+selftests-bpf-fix-compile-error-from-rlim_t-in-sk_st.patch
+selftests-bpf-fix-error-compiling-bpf_iter_setsockop.patch
+selftests-bpf-fix-missing-array_size-definition-in-b.patch
+selftests-bpf-fix-compiling-kfree_skb.c-with-musl-li.patch
+selftests-bpf-fix-compiling-flow_dissector.c-with-mu.patch
+selftests-bpf-fix-compiling-tcp_rtt.c-with-musl-libc.patch
+selftests-bpf-fix-compiling-core_reloc.c-with-musl-l.patch
+selftests-bpf-fix-errors-compiling-cg_storage_multi..patch
+selftests-bpf-fix-error-compiling-test_lru_map.c.patch
+selftests-bpf-fix-c-compile-error-from-missing-_bool.patch
+xz-cleanup-crc32-edits-from-2018.patch
+kthread-fix-task-state-in-kthread-worker-if-being-fr.patch
+ext4-clear-ext4_group_info_was_trimmed_bit-even-moun.patch
+smackfs-use-rcu_assign_pointer-to-ensure-safe-assign.patch
+ext4-avoid-buffer_head-leak-in-ext4_mark_inode_used.patch
+ext4-avoid-potential-buffer_head-leak-in-__ext4_new_.patch
+ext4-avoid-negative-min_clusters-in-find_group_orlov.patch
+ext4-return-error-on-ext4_find_inline_entry.patch
+ext4-avoid-oob-when-system.data-xattr-changes-undern.patch
+nilfs2-fix-potential-null-ptr-deref-in-nilfs_btree_i.patch
+nilfs2-determine-empty-node-blocks-as-corrupted.patch
+nilfs2-fix-potential-oob-read-in-nilfs_btree_check_d.patch
+bpf-fix-bpf_strtol-and-bpf_strtoul-helpers-for-32bit.patch
+perf-mem-free-the-allocated-sort-string-fixing-a-lea.patch
+perf-test-sample-parsing-add-endian-test-for-struct-.patch
+perf-evsel-reduce-scope-of-evsel__ignore_missing_thr.patch
+perf-evsel-rename-variable-cpu-to-index.patch
+perf-tools-support-reading-perf_format_lost.patch
+perf-inject-fix-leader-sampling-inserting-additional.patch
+perf-sched-timehist-fix-missing-free-of-session-in-p.patch
+perf-sched-timehist-fixed-timestamp-error-when-unabl.patch
+perf-time-utils-fix-32-bit-nsec-parsing.patch
+clk-imx-imx8mp-fix-clock-tree-update-of-tf-a-managed.patch
+clk-imx-imx8qxp-register-dc0_bypass0_clk-before-disp.patch
+clk-imx-imx8qxp-parent-should-be-initialized-earlier.patch
+remoteproc-imx_rproc-correct-ddr-alias-for-i.mx8m.patch
+remoteproc-imx_rproc-initialize-workqueue-earlier.patch
+clk-rockchip-set-parent-rate-for-dclk_vop-clock-on-r.patch
+input-ilitek_ts_i2c-avoid-wrong-input-subsystem-sync.patch
+input-ilitek_ts_i2c-add-report-id-message-validation.patch
+drivers-media-dvb-frontends-rtl2832-fix-an-out-of-bo.patch
+drivers-media-dvb-frontends-rtl2830-fix-an-out-of-bo.patch
+pci-keystone-fix-if-statement-expression-in-ks_pcie_.patch
+pci-xilinx-nwl-fix-register-misspelling.patch
+pci-xilinx-nwl-clean-up-clock-on-probe-failure-remov.patch
+rdma-iwcm-fix-warning-at_kernel-workqueue.c-check_fl.patch
+pinctrl-single-fix-missing-error-code-in-pcs_probe.patch
+rdma-rtrs-reset-hb_missed_cnt-after-receiving-other-.patch
+rdma-rtrs-clt-reset-cid-to-con_num-1-to-stay-in-boun.patch
+clk-ti-dra7-atl-fix-leak-of-of_nodes.patch
+nfsd-remove-unneeded-eexist-error-check-in-nfsd_do_f.patch
+nfsd-fix-refcount-leak-when-file-is-unhashed-after-b.patch
+pinctrl-mvebu-use-devm_platform_get_and_ioremap_reso.patch
+pinctrl-mvebu-fix-devinit_dove_pinctrl_probe-functio.patch
+ib-core-fix-ib_cache_setup_one-error-flow-cleanup.patch
+watchdog-imx_sc_wdt-don-t-disable-wdt-in-suspend.patch
+rdma-hns-don-t-modify-rq-next-block-addr-in-hip09-qp.patch
+rdma-hns-fix-the-overflow-risk-of-hem_list_calc_ba_r.patch
+rdma-hns-fix-spin_unlock_irqrestore-called-with-irqs.patch
+rdma-hns-remove-unused-abnormal-interrupt-of-type-ra.patch
+rdma-hns-fix-the-wrong-type-of-return-value-of-the-i.patch
+rdma-hns-refactor-the-abnormal-interrupt-handler-fun.patch
+rdma-hns-fix-vf-triggering-pf-reset-in-abnormal-inte.patch
+rdma-hns-optimize-hem-allocation-performance.patch
+input-ps2-gpio-use-irqf_no_autoen-flag-in-request_ir.patch
+riscv-fix-fp-alignment-bug-in-perf_callchain_user.patch
+rdma-cxgb4-added-null-check-for-lookup_atid.patch
+rdma-irdma-fix-error-message-in-irdma_modify_qp_roce.patch
+ntb-intel-fix-the-null-vs-is_err-bug-for-debugfs_cre.patch
+ntb_perf-fix-printk-format.patch
+nfsd-call-cache_put-if-xdr_reserve_space-returns-nul.patch
+nfsd-return-einval-when-namelen-is-0.patch
+f2fs-fix-typo.patch
+f2fs-fix-to-update-i_ctime-in-__f2fs_setxattr.patch
+f2fs-remove-unneeded-check-condition-in-__f2fs_setxa.patch
+f2fs-reduce-expensive-checkpoint-trigger-frequency.patch
+f2fs-optimize-error-handling-in-redirty_blocks.patch
+f2fs-fix-to-wait-page-writeback-before-setting-gcing.patch
+f2fs-introduce-f2fs_ipu_honor_opu_write-ipu-policy.patch
+f2fs-clean-up-w-dotdot_name.patch
+f2fs-get-rid-of-online-repaire-on-corrupted-director.patch
+spi-lpspi-silence-error-message-upon-deferred-probe.patch
+spi-lpspi-release-requested-dma-channels.patch
+spi-spi-fsl-lpspi-undo-runtime-pm-changes-at-driver-.patch
+iio-adc-ad7606-fix-oversampling-gpio-array.patch
+iio-adc-ad7606-fix-standby-gpio-state-to-match-the-d.patch
+usb-dwc2-skip-clock-gating-on-broadcom-socs.patch
+coresight-tmc-sg-do-not-leak-sg_table.patch
+interconnect-qcom-sm8250-enable-sync_state.patch
+vdpa-add-eventfd-for-the-vdpa-callback.patch
+vhost_vdpa-assign-irq-bypass-producer-token-correctl.patch
+revert-dm-requeue-io-if-mapping-table-not-yet-availa.patch
+net-axienet-clean-up-device-used-for-dma-calls.patch
+net-axienet-clean-up-dma-start-stop-and-error-handli.patch
+net-axienet-don-t-set-irq-timer-when-irq-delay-not-u.patch
+net-axienet-implement-napi-and-gro-receive.patch
+net-axienet-reduce-default-rx-interrupt-threshold-to.patch
+net-axienet-add-coalesce-timer-ethtool-configuration.patch
+net-axienet-be-more-careful-about-updating-tx_bd_tai.patch
+net-axienet-use-napi-for-tx-completion-path.patch
+net-axienet-switch-to-64-bit-rx-tx-statistics.patch
+net-xilinx-axienet-fix-packet-counting.patch
+netfilter-nf_reject_ipv6-fix-nf_reject_ip6_tcphdr_pu.patch
+net-seeq-fix-use-after-free-vulnerability-in-ether3-.patch
+net-ipv6-select-dst_cache-from-ipv6_rpl_lwtunnel.patch
+tcp-check-skb-is-non-null-in-tcp_rto_delta_us.patch
+net-qrtr-update-packets-cloning-when-broadcasting.patch
+bonding-fix-unnecessary-warnings-and-logs-from-bond_.patch
+netfilter-nf_tables-keep-deleted-flowtable-hooks-unt.patch
+netfilter-ctnetlink-compile-ctnetlink_label_size-wit.patch
--- /dev/null
+From 9f9815dbeea94cb4ad4b1a43a3efb8c8d9d785b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Sep 2024 08:47:26 +0000
+Subject: smackfs: Use rcu_assign_pointer() to ensure safe assignment in
+ smk_set_cipso
+
+From: Jiawei Ye <jiawei.ye@foxmail.com>
+
+[ Upstream commit 2749749afa071f8a0e405605de9da615e771a7ce ]
+
+In the `smk_set_cipso` function, the `skp->smk_netlabel.attr.mls.cat`
+field is directly assigned to a new value without using the appropriate
+RCU pointer assignment functions. According to RCU usage rules, this is
+illegal and can lead to unpredictable behavior, including data
+inconsistencies and impossible-to-diagnose memory corruption issues.
+
+This possible bug was identified using a static analysis tool developed
+by myself, specifically designed to detect RCU-related issues.
+
+To address this, the assignment is now done using rcu_assign_pointer(),
+which ensures that the pointer assignment is done safely, with the
+necessary memory barriers and synchronization. This change prevents
+potential RCU dereference issues by ensuring that the `cat` field is
+safely updated while still adhering to RCU's requirements.
+
+Fixes: 0817534ff9ea ("smackfs: Fix use-after-free in netlbl_catmap_walk()")
+Signed-off-by: Jiawei Ye <jiawei.ye@foxmail.com>
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/smack/smackfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
+index 27fd7744e0fc0..f6961a8895296 100644
+--- a/security/smack/smackfs.c
++++ b/security/smack/smackfs.c
+@@ -920,7 +920,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
+ rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN);
+ if (rc >= 0) {
+ old_cat = skp->smk_netlabel.attr.mls.cat;
+- skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat;
++ rcu_assign_pointer(skp->smk_netlabel.attr.mls.cat, ncats.attr.mls.cat);
+ skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl;
+ synchronize_rcu();
+ netlbl_catmap_free(old_cat);
+--
+2.43.0
+
--- /dev/null
+From 7c5417d5afceaef06c648396611c6f55d3ca599b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Sep 2024 15:44:49 +0000
+Subject: sock_map: Add a cond_resched() in sock_hash_free()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b1339be951ad31947ae19bc25cb08769bf255100 ]
+
+Several syzbot soft lockup reports all have in common sock_hash_free()
+
+If a map with a large number of buckets is destroyed, we need to yield
+the cpu when needed.
+
+Fixes: 75e68e5bf2c7 ("bpf, sockhash: Synchronize delete from bucket list on map free")
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Martin KaFai Lau <martin.lau@kernel.org>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Link: https://lore.kernel.org/bpf/20240906154449.3742932-1-edumazet@google.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock_map.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/core/sock_map.c b/net/core/sock_map.c
+index 0f9648c6bcf76..9ef58dd1139d3 100644
+--- a/net/core/sock_map.c
++++ b/net/core/sock_map.c
+@@ -1177,6 +1177,7 @@ static void sock_hash_free(struct bpf_map *map)
+ sock_put(elem->sk);
+ sock_hash_free_elem(htab, elem);
+ }
++ cond_resched();
+ }
+
+ /* wait for psock readers accessing its map link */
+--
+2.43.0
+
--- /dev/null
+From c4327178c747f48e08a4173cf832776340062594 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Nov 2021 11:31:34 +0100
+Subject: spi: lpspi: release requested DMA channels
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit f02bff30114f385d53ae3e45141db602923bca5d ]
+
+The requested DMA channels are never released. Do this in .remove as well
+as in .probe. spi_register_controller() can return -EPROBE_DEFER if
+cs-gpios are not probed yet.
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Link: https://lore.kernel.org/r/20211109103134.184216-1-alexander.stein@ew.tq-group.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 3b577de206d5 ("spi: spi-fsl-lpspi: Undo runtime PM changes at driver exit time")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-fsl-lpspi.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c
+index bc3e434ba2986..314629b172281 100644
+--- a/drivers/spi/spi-fsl-lpspi.c
++++ b/drivers/spi/spi-fsl-lpspi.c
+@@ -920,7 +920,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
+ ret = devm_spi_register_controller(&pdev->dev, controller);
+ if (ret < 0) {
+ dev_err_probe(&pdev->dev, ret, "spi_register_controller error: %i\n", ret);
+- goto out_pm_get;
++ goto free_dma;
+ }
+
+ pm_runtime_mark_last_busy(fsl_lpspi->dev);
+@@ -928,6 +928,8 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
+
+ return 0;
+
++free_dma:
++ fsl_lpspi_dma_exit(controller);
+ out_pm_get:
+ pm_runtime_dont_use_autosuspend(fsl_lpspi->dev);
+ pm_runtime_put_sync(fsl_lpspi->dev);
+@@ -944,6 +946,8 @@ static int fsl_lpspi_remove(struct platform_device *pdev)
+ struct fsl_lpspi_data *fsl_lpspi =
+ spi_controller_get_devdata(controller);
+
++ fsl_lpspi_dma_exit(controller);
++
+ pm_runtime_disable(fsl_lpspi->dev);
+ return 0;
+ }
+--
+2.43.0
+
--- /dev/null
+From 91a12b12c208cf79e57987e91c3c529fdf6e9d72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Nov 2021 15:55:23 +0100
+Subject: spi: lpspi: Silence error message upon deferred probe
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit 12f62a857c83b2efcbf8d9961aacd352bf81ad3d ]
+
+Do not print error messages with error code -517. Silences the following
+errors upon on imx8qm:
+fsl_lpspi 5a000000.spi: spi_register_controller error: -517
+fsl_lpspi 5a010000.spi: spi_register_controller error: -517
+fsl_lpspi 5a020000.spi: spi_register_controller error: -517
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Link: https://lore.kernel.org/r/20211108145523.1797609-1-alexander.stein@ew.tq-group.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 3b577de206d5 ("spi: spi-fsl-lpspi: Undo runtime PM changes at driver exit time")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-fsl-lpspi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c
+index c21d7959dcd23..bc3e434ba2986 100644
+--- a/drivers/spi/spi-fsl-lpspi.c
++++ b/drivers/spi/spi-fsl-lpspi.c
+@@ -919,7 +919,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
+
+ ret = devm_spi_register_controller(&pdev->dev, controller);
+ if (ret < 0) {
+- dev_err(&pdev->dev, "spi_register_controller error.\n");
++ dev_err_probe(&pdev->dev, ret, "spi_register_controller error: %i\n", ret);
+ goto out_pm_get;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 47db0d97afac9ce0e4c97573ff161ac244577358 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Aug 2024 17:45:12 +0300
+Subject: spi: ppc4xx: Avoid returning 0 when failed to parse and map IRQ
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 7781f1d120fec8624fc654eda900fc8748262082 ]
+
+0 is incorrect error code when failed to parse and map IRQ.
+Replace OF specific old API for IRQ retrieval with a generic
+one to fix this issue.
+
+Fixes: 0f245463b01e ("spi: ppc4xx: handle irq_of_parse_and_map() errors")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://patch.msgid.link/20240814144525.2648450-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-ppc4xx.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c
+index edfe0896046f9..be1dd4e6a3e7d 100644
+--- a/drivers/spi/spi-ppc4xx.c
++++ b/drivers/spi/spi-ppc4xx.c
+@@ -26,7 +26,6 @@
+ #include <linux/errno.h>
+ #include <linux/wait.h>
+ #include <linux/of_address.h>
+-#include <linux/of_irq.h>
+ #include <linux/of_platform.h>
+ #include <linux/interrupt.h>
+ #include <linux/delay.h>
+@@ -410,9 +409,10 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
+ }
+
+ /* Request IRQ */
+- hw->irqnum = irq_of_parse_and_map(np, 0);
+- if (hw->irqnum <= 0)
++ ret = platform_get_irq(op, 0);
++ if (ret < 0)
+ goto free_host;
++ hw->irqnum = ret;
+
+ ret = request_irq(hw->irqnum, spi_ppc4xx_int,
+ 0, "spi_ppc4xx_of", (void *)hw);
+--
+2.43.0
+
--- /dev/null
+From 6820f68d70dd184057a3932b717eb54e5a00122a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jul 2024 16:40:47 +0800
+Subject: spi: ppc4xx: handle irq_of_parse_and_map() errors
+
+From: Ma Ke <make24@iscas.ac.cn>
+
+[ Upstream commit 0f245463b01ea254ae90e1d0389e90b0e7d8dc75 ]
+
+Zero and negative number is not a valid IRQ for in-kernel code and the
+irq_of_parse_and_map() function returns zero on error. So this check for
+valid IRQs should only accept values > 0.
+
+Fixes: 44dab88e7cc9 ("spi: add spi_ppc4xx driver")
+Signed-off-by: Ma Ke <make24@iscas.ac.cn>
+Link: https://patch.msgid.link/20240724084047.1506084-1-make24@iscas.ac.cn
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-ppc4xx.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c
+index 1179a1115137f..edfe0896046f9 100644
+--- a/drivers/spi/spi-ppc4xx.c
++++ b/drivers/spi/spi-ppc4xx.c
+@@ -411,6 +411,9 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
+
+ /* Request IRQ */
+ hw->irqnum = irq_of_parse_and_map(np, 0);
++ if (hw->irqnum <= 0)
++ goto free_host;
++
+ ret = request_irq(hw->irqnum, spi_ppc4xx_int,
+ 0, "spi_ppc4xx_of", (void *)hw);
+ if (ret) {
+--
+2.43.0
+
--- /dev/null
+From 359719b686460af497a1f87a534ab438cfe3035e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Sep 2024 10:12:51 +0800
+Subject: spi: spi-fsl-lpspi: Undo runtime PM changes at driver exit time
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 3b577de206d52dbde9428664b6d823d35a803d75 ]
+
+It's important to undo pm_runtime_use_autosuspend() with
+pm_runtime_dont_use_autosuspend() at driver exit time unless driver
+initially enabled pm_runtime with devm_pm_runtime_enable()
+(which handles it for you).
+
+Hence, call pm_runtime_dont_use_autosuspend() at driver exit time
+to fix it.
+
+Fixes: 944c01a889d9 ("spi: lpspi: enable runtime pm for lpspi")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Link: https://patch.msgid.link/20240906021251.610462-1-ruanjinjie@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-fsl-lpspi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c
+index 314629b172281..b6674fb6c1d67 100644
+--- a/drivers/spi/spi-fsl-lpspi.c
++++ b/drivers/spi/spi-fsl-lpspi.c
+@@ -948,6 +948,7 @@ static int fsl_lpspi_remove(struct platform_device *pdev)
+
+ fsl_lpspi_dma_exit(controller);
+
++ pm_runtime_dont_use_autosuspend(fsl_lpspi->dev);
+ pm_runtime_disable(fsl_lpspi->dev);
+ return 0;
+ }
+--
+2.43.0
+
--- /dev/null
+From 85f21007ef34b12ba4c46af73b40c7a781e224ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Sep 2024 15:08:22 -0400
+Subject: tcp: check skb is non-NULL in tcp_rto_delta_us()
+
+From: Josh Hunt <johunt@akamai.com>
+
+[ Upstream commit c8770db2d54437a5f49417ae7b46f7de23d14db6 ]
+
+We have some machines running stock Ubuntu 20.04.6 which is their 5.4.0-174-generic
+kernel that are running ceph and recently hit a null ptr dereference in
+tcp_rearm_rto(). Initially hitting it from the TLP path, but then later we also
+saw it getting hit from the RACK case as well. Here are examples of the oops
+messages we saw in each of those cases:
+
+Jul 26 15:05:02 rx [11061395.780353] BUG: kernel NULL pointer dereference, address: 0000000000000020
+Jul 26 15:05:02 rx [11061395.787572] #PF: supervisor read access in kernel mode
+Jul 26 15:05:02 rx [11061395.792971] #PF: error_code(0x0000) - not-present page
+Jul 26 15:05:02 rx [11061395.798362] PGD 0 P4D 0
+Jul 26 15:05:02 rx [11061395.801164] Oops: 0000 [#1] SMP NOPTI
+Jul 26 15:05:02 rx [11061395.805091] CPU: 0 PID: 9180 Comm: msgr-worker-1 Tainted: G W 5.4.0-174-generic #193-Ubuntu
+Jul 26 15:05:02 rx [11061395.814996] Hardware name: Supermicro SMC 2x26 os-gen8 64C NVME-Y 256G/H12SSW-NTR, BIOS 2.5.V1.2U.NVMe.UEFI 05/09/2023
+Jul 26 15:05:02 rx [11061395.825952] RIP: 0010:tcp_rearm_rto+0xe4/0x160
+Jul 26 15:05:02 rx [11061395.830656] Code: 87 ca 04 00 00 00 5b 41 5c 41 5d 5d c3 c3 49 8b bc 24 40 06 00 00 eb 8d 48 bb cf f7 53 e3 a5 9b c4 20 4c 89 ef e8 0c fe 0e 00 <48> 8b 78 20 48 c1 ef 03 48 89 f8 41 8b bc 24 80 04 00 00 48 f7 e3
+Jul 26 15:05:02 rx [11061395.849665] RSP: 0018:ffffb75d40003e08 EFLAGS: 00010246
+Jul 26 15:05:02 rx [11061395.855149] RAX: 0000000000000000 RBX: 20c49ba5e353f7cf RCX: 0000000000000000
+Jul 26 15:05:02 rx [11061395.862542] RDX: 0000000062177c30 RSI: 000000000000231c RDI: ffff9874ad283a60
+Jul 26 15:05:02 rx [11061395.869933] RBP: ffffb75d40003e20 R08: 0000000000000000 R09: ffff987605e20aa8
+Jul 26 15:05:02 rx [11061395.877318] R10: ffffb75d40003f00 R11: ffffb75d4460f740 R12: ffff9874ad283900
+Jul 26 15:05:02 rx [11061395.884710] R13: ffff9874ad283a60 R14: ffff9874ad283980 R15: ffff9874ad283d30
+Jul 26 15:05:02 rx [11061395.892095] FS: 00007f1ef4a2e700(0000) GS:ffff987605e00000(0000) knlGS:0000000000000000
+Jul 26 15:05:02 rx [11061395.900438] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+Jul 26 15:05:02 rx [11061395.906435] CR2: 0000000000000020 CR3: 0000003e450ba003 CR4: 0000000000760ef0
+Jul 26 15:05:02 rx [11061395.913822] PKRU: 55555554
+Jul 26 15:05:02 rx [11061395.916786] Call Trace:
+Jul 26 15:05:02 rx [11061395.919488]
+Jul 26 15:05:02 rx [11061395.921765] ? show_regs.cold+0x1a/0x1f
+Jul 26 15:05:02 rx [11061395.925859] ? __die+0x90/0xd9
+Jul 26 15:05:02 rx [11061395.929169] ? no_context+0x196/0x380
+Jul 26 15:05:02 rx [11061395.933088] ? ip6_protocol_deliver_rcu+0x4e0/0x4e0
+Jul 26 15:05:02 rx [11061395.938216] ? ip6_sublist_rcv_finish+0x3d/0x50
+Jul 26 15:05:02 rx [11061395.943000] ? __bad_area_nosemaphore+0x50/0x1a0
+Jul 26 15:05:02 rx [11061395.947873] ? bad_area_nosemaphore+0x16/0x20
+Jul 26 15:05:02 rx [11061395.952486] ? do_user_addr_fault+0x267/0x450
+Jul 26 15:05:02 rx [11061395.957104] ? ipv6_list_rcv+0x112/0x140
+Jul 26 15:05:02 rx [11061395.961279] ? __do_page_fault+0x58/0x90
+Jul 26 15:05:02 rx [11061395.965458] ? do_page_fault+0x2c/0xe0
+Jul 26 15:05:02 rx [11061395.969465] ? page_fault+0x34/0x40
+Jul 26 15:05:02 rx [11061395.973217] ? tcp_rearm_rto+0xe4/0x160
+Jul 26 15:05:02 rx [11061395.977313] ? tcp_rearm_rto+0xe4/0x160
+Jul 26 15:05:02 rx [11061395.981408] tcp_send_loss_probe+0x10b/0x220
+Jul 26 15:05:02 rx [11061395.985937] tcp_write_timer_handler+0x1b4/0x240
+Jul 26 15:05:02 rx [11061395.990809] tcp_write_timer+0x9e/0xe0
+Jul 26 15:05:02 rx [11061395.994814] ? tcp_write_timer_handler+0x240/0x240
+Jul 26 15:05:02 rx [11061395.999866] call_timer_fn+0x32/0x130
+Jul 26 15:05:02 rx [11061396.003782] __run_timers.part.0+0x180/0x280
+Jul 26 15:05:02 rx [11061396.008309] ? recalibrate_cpu_khz+0x10/0x10
+Jul 26 15:05:02 rx [11061396.012841] ? native_x2apic_icr_write+0x30/0x30
+Jul 26 15:05:02 rx [11061396.017718] ? lapic_next_event+0x21/0x30
+Jul 26 15:05:02 rx [11061396.021984] ? clockevents_program_event+0x8f/0xe0
+Jul 26 15:05:02 rx [11061396.027035] run_timer_softirq+0x2a/0x50
+Jul 26 15:05:02 rx [11061396.031212] __do_softirq+0xd1/0x2c1
+Jul 26 15:05:02 rx [11061396.035044] do_softirq_own_stack+0x2a/0x40
+Jul 26 15:05:02 rx [11061396.039480]
+Jul 26 15:05:02 rx [11061396.041840] do_softirq.part.0+0x46/0x50
+Jul 26 15:05:02 rx [11061396.046022] __local_bh_enable_ip+0x50/0x60
+Jul 26 15:05:02 rx [11061396.050460] _raw_spin_unlock_bh+0x1e/0x20
+Jul 26 15:05:02 rx [11061396.054817] nf_conntrack_tcp_packet+0x29e/0xbe0 [nf_conntrack]
+Jul 26 15:05:02 rx [11061396.060994] ? get_l4proto+0xe7/0x190 [nf_conntrack]
+Jul 26 15:05:02 rx [11061396.066220] nf_conntrack_in+0xe9/0x670 [nf_conntrack]
+Jul 26 15:05:02 rx [11061396.071618] ipv6_conntrack_local+0x14/0x20 [nf_conntrack]
+Jul 26 15:05:02 rx [11061396.077356] nf_hook_slow+0x45/0xb0
+Jul 26 15:05:02 rx [11061396.081098] ip6_xmit+0x3f0/0x5d0
+Jul 26 15:05:02 rx [11061396.084670] ? ipv6_anycast_cleanup+0x50/0x50
+Jul 26 15:05:02 rx [11061396.089282] ? __sk_dst_check+0x38/0x70
+Jul 26 15:05:02 rx [11061396.093381] ? inet6_csk_route_socket+0x13b/0x200
+Jul 26 15:05:02 rx [11061396.098346] inet6_csk_xmit+0xa7/0xf0
+Jul 26 15:05:02 rx [11061396.102263] __tcp_transmit_skb+0x550/0xb30
+Jul 26 15:05:02 rx [11061396.106701] tcp_write_xmit+0x3c6/0xc20
+Jul 26 15:05:02 rx [11061396.110792] ? __alloc_skb+0x98/0x1d0
+Jul 26 15:05:02 rx [11061396.114708] __tcp_push_pending_frames+0x37/0x100
+Jul 26 15:05:02 rx [11061396.119667] tcp_push+0xfd/0x100
+Jul 26 15:05:02 rx [11061396.123150] tcp_sendmsg_locked+0xc70/0xdd0
+Jul 26 15:05:02 rx [11061396.127588] tcp_sendmsg+0x2d/0x50
+Jul 26 15:05:02 rx [11061396.131245] inet6_sendmsg+0x43/0x70
+Jul 26 15:05:02 rx [11061396.135075] __sock_sendmsg+0x48/0x70
+Jul 26 15:05:02 rx [11061396.138994] ____sys_sendmsg+0x212/0x280
+Jul 26 15:05:02 rx [11061396.143172] ___sys_sendmsg+0x88/0xd0
+Jul 26 15:05:02 rx [11061396.147098] ? __seccomp_filter+0x7e/0x6b0
+Jul 26 15:05:02 rx [11061396.151446] ? __switch_to+0x39c/0x460
+Jul 26 15:05:02 rx [11061396.155453] ? __switch_to_asm+0x42/0x80
+Jul 26 15:05:02 rx [11061396.159636] ? __switch_to_asm+0x5a/0x80
+Jul 26 15:05:02 rx [11061396.163816] __sys_sendmsg+0x5c/0xa0
+Jul 26 15:05:02 rx [11061396.167647] __x64_sys_sendmsg+0x1f/0x30
+Jul 26 15:05:02 rx [11061396.171832] do_syscall_64+0x57/0x190
+Jul 26 15:05:02 rx [11061396.175748] entry_SYSCALL_64_after_hwframe+0x5c/0xc1
+Jul 26 15:05:02 rx [11061396.181055] RIP: 0033:0x7f1ef692618d
+Jul 26 15:05:02 rx [11061396.184893] Code: 28 89 54 24 1c 48 89 74 24 10 89 7c 24 08 e8 ca ee ff ff 8b 54 24 1c 48 8b 74 24 10 41 89 c0 8b 7c 24 08 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 2f 44 89 c7 48 89 44 24 08 e8 fe ee ff ff 48
+Jul 26 15:05:02 rx [11061396.203889] RSP: 002b:00007f1ef4a26aa0 EFLAGS: 00000293 ORIG_RAX: 000000000000002e
+Jul 26 15:05:02 rx [11061396.211708] RAX: ffffffffffffffda RBX: 000000000000084b RCX: 00007f1ef692618d
+Jul 26 15:05:02 rx [11061396.219091] RDX: 0000000000004000 RSI: 00007f1ef4a26b10 RDI: 0000000000000275
+Jul 26 15:05:02 rx [11061396.226475] RBP: 0000000000004000 R08: 0000000000000000 R09: 0000000000000020
+Jul 26 15:05:02 rx [11061396.233859] R10: 0000000000000000 R11: 0000000000000293 R12: 000000000000084b
+Jul 26 15:05:02 rx [11061396.241243] R13: 00007f1ef4a26b10 R14: 0000000000000275 R15: 000055592030f1e8
+Jul 26 15:05:02 rx [11061396.248628] Modules linked in: vrf bridge stp llc vxlan ip6_udp_tunnel udp_tunnel nls_iso8859_1 amd64_edac_mod edac_mce_amd kvm_amd kvm crct10dif_pclmul ghash_clmulni_intel aesni_intel crypto_simd cryptd glue_helper wmi_bmof ipmi_ssif input_leds joydev rndis_host cdc_ether usbnet mii ast drm_vram_helper ttm drm_kms_helper i2c_algo_bit fb_sys_fops syscopyarea sysfillrect sysimgblt ccp mac_hid ipmi_si ipmi_devintf ipmi_msghandler nft_ct sch_fq_codel nf_tables_set nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nf_tables nfnetlink ramoops reed_solomon efi_pstore drm ip_tables x_tables autofs4 raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq libcrc32c raid0 multipath linear mlx5_ib ib_uverbs ib_core raid1 mlx5_core hid_generic pci_hyperv_intf crc32_pclmul tls usbhid ahci mlxfw bnxt_en libahci hid nvme i2c_piix4 nvme_core wmi
+Jul 26 15:05:02 rx [11061396.324334] CR2: 0000000000000020
+Jul 26 15:05:02 rx [11061396.327944] ---[ end trace 68a2b679d1cfb4f1 ]---
+Jul 26 15:05:02 rx [11061396.433435] RIP: 0010:tcp_rearm_rto+0xe4/0x160
+Jul 26 15:05:02 rx [11061396.438137] Code: 87 ca 04 00 00 00 5b 41 5c 41 5d 5d c3 c3 49 8b bc 24 40 06 00 00 eb 8d 48 bb cf f7 53 e3 a5 9b c4 20 4c 89 ef e8 0c fe 0e 00 <48> 8b 78 20 48 c1 ef 03 48 89 f8 41 8b bc 24 80 04 00 00 48 f7 e3
+Jul 26 15:05:02 rx [11061396.457144] RSP: 0018:ffffb75d40003e08 EFLAGS: 00010246
+Jul 26 15:05:02 rx [11061396.462629] RAX: 0000000000000000 RBX: 20c49ba5e353f7cf RCX: 0000000000000000
+Jul 26 15:05:02 rx [11061396.470012] RDX: 0000000062177c30 RSI: 000000000000231c RDI: ffff9874ad283a60
+Jul 26 15:05:02 rx [11061396.477396] RBP: ffffb75d40003e20 R08: 0000000000000000 R09: ffff987605e20aa8
+Jul 26 15:05:02 rx [11061396.484779] R10: ffffb75d40003f00 R11: ffffb75d4460f740 R12: ffff9874ad283900
+Jul 26 15:05:02 rx [11061396.492164] R13: ffff9874ad283a60 R14: ffff9874ad283980 R15: ffff9874ad283d30
+Jul 26 15:05:02 rx [11061396.499547] FS: 00007f1ef4a2e700(0000) GS:ffff987605e00000(0000) knlGS:0000000000000000
+Jul 26 15:05:02 rx [11061396.507886] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+Jul 26 15:05:02 rx [11061396.513884] CR2: 0000000000000020 CR3: 0000003e450ba003 CR4: 0000000000760ef0
+Jul 26 15:05:02 rx [11061396.521267] PKRU: 55555554
+Jul 26 15:05:02 rx [11061396.524230] Kernel panic - not syncing: Fatal exception in interrupt
+Jul 26 15:05:02 rx [11061396.530885] Kernel Offset: 0x1b200000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
+Jul 26 15:05:03 rx [11061396.660181] ---[ end Kernel panic - not syncing: Fatal
+ exception in interrupt ]---
+
+After we hit this we disabled TLP by setting tcp_early_retrans to 0 and then hit the crash in the RACK case:
+
+Aug 7 07:26:16 rx [1006006.265582] BUG: kernel NULL pointer dereference, address: 0000000000000020
+Aug 7 07:26:16 rx [1006006.272719] #PF: supervisor read access in kernel mode
+Aug 7 07:26:16 rx [1006006.278030] #PF: error_code(0x0000) - not-present page
+Aug 7 07:26:16 rx [1006006.283343] PGD 0 P4D 0
+Aug 7 07:26:16 rx [1006006.286057] Oops: 0000 [#1] SMP NOPTI
+Aug 7 07:26:16 rx [1006006.289896] CPU: 5 PID: 0 Comm: swapper/5 Tainted: G W 5.4.0-174-generic #193-Ubuntu
+Aug 7 07:26:16 rx [1006006.299107] Hardware name: Supermicro SMC 2x26 os-gen8 64C NVME-Y 256G/H12SSW-NTR, BIOS 2.5.V1.2U.NVMe.UEFI 05/09/2023
+Aug 7 07:26:16 rx [1006006.309970] RIP: 0010:tcp_rearm_rto+0xe4/0x160
+Aug 7 07:26:16 rx [1006006.314584] Code: 87 ca 04 00 00 00 5b 41 5c 41 5d 5d c3 c3 49 8b bc 24 40 06 00 00 eb 8d 48 bb cf f7 53 e3 a5 9b c4 20 4c 89 ef e8 0c fe 0e 00 <48> 8b 78 20 48 c1 ef 03 48 89 f8 41 8b bc 24 80 04 00 00 48 f7 e3
+Aug 7 07:26:16 rx [1006006.333499] RSP: 0018:ffffb42600a50960 EFLAGS: 00010246
+Aug 7 07:26:16 rx [1006006.338895] RAX: 0000000000000000 RBX: 20c49ba5e353f7cf RCX: 0000000000000000
+Aug 7 07:26:16 rx [1006006.346193] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff92d687ed8160
+Aug 7 07:26:16 rx [1006006.353489] RBP: ffffb42600a50978 R08: 0000000000000000 R09: 00000000cd896dcc
+Aug 7 07:26:16 rx [1006006.360786] R10: ffff92dc3404f400 R11: 0000000000000001 R12: ffff92d687ed8000
+Aug 7 07:26:16 rx [1006006.368084] R13: ffff92d687ed8160 R14: 00000000cd896dcc R15: 00000000cd8fca81
+Aug 7 07:26:16 rx [1006006.375381] FS: 0000000000000000(0000) GS:ffff93158ad40000(0000) knlGS:0000000000000000
+Aug 7 07:26:16 rx [1006006.383632] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+Aug 7 07:26:16 rx [1006006.389544] CR2: 0000000000000020 CR3: 0000003e775ce006 CR4: 0000000000760ee0
+Aug 7 07:26:16 rx [1006006.396839] PKRU: 55555554
+Aug 7 07:26:16 rx [1006006.399717] Call Trace:
+Aug 7 07:26:16 rx [1006006.402335]
+Aug 7 07:26:16 rx [1006006.404525] ? show_regs.cold+0x1a/0x1f
+Aug 7 07:26:16 rx [1006006.408532] ? __die+0x90/0xd9
+Aug 7 07:26:16 rx [1006006.411760] ? no_context+0x196/0x380
+Aug 7 07:26:16 rx [1006006.415599] ? __bad_area_nosemaphore+0x50/0x1a0
+Aug 7 07:26:16 rx [1006006.420392] ? _raw_spin_lock+0x1e/0x30
+Aug 7 07:26:16 rx [1006006.424401] ? bad_area_nosemaphore+0x16/0x20
+Aug 7 07:26:16 rx [1006006.428927] ? do_user_addr_fault+0x267/0x450
+Aug 7 07:26:16 rx [1006006.433450] ? __do_page_fault+0x58/0x90
+Aug 7 07:26:16 rx [1006006.437542] ? do_page_fault+0x2c/0xe0
+Aug 7 07:26:16 rx [1006006.441470] ? page_fault+0x34/0x40
+Aug 7 07:26:16 rx [1006006.445134] ? tcp_rearm_rto+0xe4/0x160
+Aug 7 07:26:16 rx [1006006.449145] tcp_ack+0xa32/0xb30
+Aug 7 07:26:16 rx [1006006.452542] tcp_rcv_established+0x13c/0x670
+Aug 7 07:26:16 rx [1006006.456981] ? sk_filter_trim_cap+0x48/0x220
+Aug 7 07:26:16 rx [1006006.461419] tcp_v6_do_rcv+0xdb/0x450
+Aug 7 07:26:16 rx [1006006.465257] tcp_v6_rcv+0xc2b/0xd10
+Aug 7 07:26:16 rx [1006006.468918] ip6_protocol_deliver_rcu+0xd3/0x4e0
+Aug 7 07:26:16 rx [1006006.473706] ip6_input_finish+0x15/0x20
+Aug 7 07:26:16 rx [1006006.477710] ip6_input+0xa2/0xb0
+Aug 7 07:26:16 rx [1006006.481109] ? ip6_protocol_deliver_rcu+0x4e0/0x4e0
+Aug 7 07:26:16 rx [1006006.486151] ip6_sublist_rcv_finish+0x3d/0x50
+Aug 7 07:26:16 rx [1006006.490679] ip6_sublist_rcv+0x1aa/0x250
+Aug 7 07:26:16 rx [1006006.494779] ? ip6_rcv_finish_core.isra.0+0xa0/0xa0
+Aug 7 07:26:16 rx [1006006.499828] ipv6_list_rcv+0x112/0x140
+Aug 7 07:26:16 rx [1006006.503748] __netif_receive_skb_list_core+0x1a4/0x250
+Aug 7 07:26:16 rx [1006006.509057] netif_receive_skb_list_internal+0x1a1/0x2b0
+Aug 7 07:26:16 rx [1006006.514538] gro_normal_list.part.0+0x1e/0x40
+Aug 7 07:26:16 rx [1006006.519068] napi_complete_done+0x91/0x130
+Aug 7 07:26:16 rx [1006006.523352] mlx5e_napi_poll+0x18e/0x610 [mlx5_core]
+Aug 7 07:26:16 rx [1006006.528481] net_rx_action+0x142/0x390
+Aug 7 07:26:16 rx [1006006.532398] __do_softirq+0xd1/0x2c1
+Aug 7 07:26:16 rx [1006006.536142] irq_exit+0xae/0xb0
+Aug 7 07:26:16 rx [1006006.539452] do_IRQ+0x5a/0xf0
+Aug 7 07:26:16 rx [1006006.542590] common_interrupt+0xf/0xf
+Aug 7 07:26:16 rx [1006006.546421]
+Aug 7 07:26:16 rx [1006006.548695] RIP: 0010:native_safe_halt+0xe/0x10
+Aug 7 07:26:16 rx [1006006.553399] Code: 7b ff ff ff eb bd 90 90 90 90 90 90 e9 07 00 00 00 0f 00 2d 36 2c 50 00 f4 c3 66 90 e9 07 00 00 00 0f 00 2d 26 2c 50 00 fb f4 90 0f 1f 44 00 00 55 48 89 e5 41 55 41 54 53 e8 dd 5e 61 ff 65
+Aug 7 07:26:16 rx [1006006.572309] RSP: 0018:ffffb42600177e70 EFLAGS: 00000246 ORIG_RAX: ffffffffffffffc2
+Aug 7 07:26:16 rx [1006006.580040] RAX: ffffffff8ed08b20 RBX: 0000000000000005 RCX: 0000000000000001
+Aug 7 07:26:16 rx [1006006.587337] RDX: 00000000f48eeca2 RSI: 0000000000000082 RDI: 0000000000000082
+Aug 7 07:26:16 rx [1006006.594635] RBP: ffffb42600177e90 R08: 0000000000000000 R09: 000000000000020f
+Aug 7 07:26:16 rx [1006006.601931] R10: 0000000000100000 R11: 0000000000000000 R12: 0000000000000005
+Aug 7 07:26:16 rx [1006006.609229] R13: ffff93157deb5f00 R14: 0000000000000000 R15: 0000000000000000
+Aug 7 07:26:16 rx [1006006.616530] ? __cpuidle_text_start+0x8/0x8
+Aug 7 07:26:16 rx [1006006.620886] ? default_idle+0x20/0x140
+Aug 7 07:26:16 rx [1006006.624804] arch_cpu_idle+0x15/0x20
+Aug 7 07:26:16 rx [1006006.628545] default_idle_call+0x23/0x30
+Aug 7 07:26:16 rx [1006006.632640] do_idle+0x1fb/0x270
+Aug 7 07:26:16 rx [1006006.636035] cpu_startup_entry+0x20/0x30
+Aug 7 07:26:16 rx [1006006.640126] start_secondary+0x178/0x1d0
+Aug 7 07:26:16 rx [1006006.644218] secondary_startup_64+0xa4/0xb0
+Aug 7 07:26:17 rx [1006006.648568] Modules linked in: vrf bridge stp llc vxlan ip6_udp_tunnel udp_tunnel nls_iso8859_1 nft_ct amd64_edac_mod edac_mce_amd kvm_amd kvm crct10dif_pclmul ghash_clmulni_intel aesni_intel crypto_simd cryptd glue_helper wmi_bmof ipmi_ssif input_leds joydev rndis_host cdc_ether usbnet ast mii drm_vram_helper ttm drm_kms_helper i2c_algo_bit fb_sys_fops syscopyarea sysfillrect sysimgblt ccp mac_hid ipmi_si ipmi_devintf ipmi_msghandler sch_fq_codel nf_tables_set nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nf_tables nfnetlink ramoops reed_solomon efi_pstore drm ip_tables x_tables autofs4 raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq libcrc32c raid0 multipath linear mlx5_ib ib_uverbs ib_core raid1 hid_generic mlx5_core pci_hyperv_intf crc32_pclmul usbhid ahci tls mlxfw bnxt_en hid libahci nvme i2c_piix4 nvme_core wmi [last unloaded: cpuid]
+Aug 7 07:26:17 rx [1006006.726180] CR2: 0000000000000020
+Aug 7 07:26:17 rx [1006006.729718] ---[ end trace e0e2e37e4e612984 ]---
+
+Prior to seeing the first crash and on other machines we also see the warning in
+tcp_send_loss_probe() where packets_out is non-zero, but both transmit and retrans
+queues are empty so we know the box is seeing some accounting issue in this area:
+
+Jul 26 09:15:27 kernel: ------------[ cut here ]------------
+Jul 26 09:15:27 kernel: invalid inflight: 2 state 1 cwnd 68 mss 8988
+Jul 26 09:15:27 kernel: WARNING: CPU: 16 PID: 0 at net/ipv4/tcp_output.c:2605 tcp_send_loss_probe+0x214/0x220
+Jul 26 09:15:27 kernel: Modules linked in: vrf bridge stp llc vxlan ip6_udp_tunnel udp_tunnel nls_iso8859_1 nft_ct amd64_edac_mod edac_mce_amd kvm_amd kvm crct10dif_pclmul ghash_clmulni_intel aesni_intel crypto_simd cryptd glue_helper wmi_bmof ipmi_ssif joydev input_leds rndis_host cdc_ether usbnet mii ast drm_vram_helper ttm drm_kms_he>
+Jul 26 09:15:27 kernel: CPU: 16 PID: 0 Comm: swapper/16 Not tainted 5.4.0-174-generic #193-Ubuntu
+Jul 26 09:15:27 kernel: Hardware name: Supermicro SMC 2x26 os-gen8 64C NVME-Y 256G/H12SSW-NTR, BIOS 2.5.V1.2U.NVMe.UEFI 05/09/2023
+Jul 26 09:15:27 kernel: RIP: 0010:tcp_send_loss_probe+0x214/0x220
+Jul 26 09:15:27 kernel: Code: 08 26 01 00 75 e2 41 0f b6 54 24 12 41 8b 8c 24 c0 06 00 00 45 89 f0 48 c7 c7 e0 b4 20 a7 c6 05 8d 08 26 01 01 e8 4a c0 0f 00 <0f> 0b eb ba 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 55 48 89 e5 41
+Jul 26 09:15:27 kernel: RSP: 0018:ffffb7838088ce00 EFLAGS: 00010286
+Jul 26 09:15:27 kernel: RAX: 0000000000000000 RBX: ffff9b84b5630430 RCX: 0000000000000006
+Jul 26 09:15:27 kernel: RDX: 0000000000000007 RSI: 0000000000000096 RDI: ffff9b8e4621c8c0
+Jul 26 09:15:27 kernel: RBP: ffffb7838088ce18 R08: 0000000000000927 R09: 0000000000000004
+Jul 26 09:15:27 kernel: R10: 0000000000000000 R11: 0000000000000001 R12: ffff9b84b5630000
+Jul 26 09:15:27 kernel: R13: 0000000000000000 R14: 000000000000231c R15: ffff9b84b5630430
+Jul 26 09:15:27 kernel: FS: 0000000000000000(0000) GS:ffff9b8e46200000(0000) knlGS:0000000000000000
+Jul 26 09:15:27 kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+Jul 26 09:15:27 kernel: CR2: 000056238cec2380 CR3: 0000003e49ede005 CR4: 0000000000760ee0
+Jul 26 09:15:27 kernel: PKRU: 55555554
+Jul 26 09:15:27 kernel: Call Trace:
+Jul 26 09:15:27 kernel: <IRQ>
+Jul 26 09:15:27 kernel: ? show_regs.cold+0x1a/0x1f
+Jul 26 09:15:27 kernel: ? __warn+0x98/0xe0
+Jul 26 09:15:27 kernel: ? tcp_send_loss_probe+0x214/0x220
+Jul 26 09:15:27 kernel: ? report_bug+0xd1/0x100
+Jul 26 09:15:27 kernel: ? do_error_trap+0x9b/0xc0
+Jul 26 09:15:27 kernel: ? do_invalid_op+0x3c/0x50
+Jul 26 09:15:27 kernel: ? tcp_send_loss_probe+0x214/0x220
+Jul 26 09:15:27 kernel: ? invalid_op+0x1e/0x30
+Jul 26 09:15:27 kernel: ? tcp_send_loss_probe+0x214/0x220
+Jul 26 09:15:27 kernel: tcp_write_timer_handler+0x1b4/0x240
+Jul 26 09:15:27 kernel: tcp_write_timer+0x9e/0xe0
+Jul 26 09:15:27 kernel: ? tcp_write_timer_handler+0x240/0x240
+Jul 26 09:15:27 kernel: call_timer_fn+0x32/0x130
+Jul 26 09:15:27 kernel: __run_timers.part.0+0x180/0x280
+Jul 26 09:15:27 kernel: ? timerqueue_add+0x9b/0xb0
+Jul 26 09:15:27 kernel: ? enqueue_hrtimer+0x3d/0x90
+Jul 26 09:15:27 kernel: ? do_error_trap+0x9b/0xc0
+Jul 26 09:15:27 kernel: ? do_invalid_op+0x3c/0x50
+Jul 26 09:15:27 kernel: ? tcp_send_loss_probe+0x214/0x220
+Jul 26 09:15:27 kernel: ? invalid_op+0x1e/0x30
+Jul 26 09:15:27 kernel: ? tcp_send_loss_probe+0x214/0x220
+Jul 26 09:15:27 kernel: tcp_write_timer_handler+0x1b4/0x240
+Jul 26 09:15:27 kernel: tcp_write_timer+0x9e/0xe0
+Jul 26 09:15:27 kernel: ? tcp_write_timer_handler+0x240/0x240
+Jul 26 09:15:27 kernel: call_timer_fn+0x32/0x130
+Jul 26 09:15:27 kernel: __run_timers.part.0+0x180/0x280
+Jul 26 09:15:27 kernel: ? timerqueue_add+0x9b/0xb0
+Jul 26 09:15:27 kernel: ? enqueue_hrtimer+0x3d/0x90
+Jul 26 09:15:27 kernel: ? recalibrate_cpu_khz+0x10/0x10
+Jul 26 09:15:27 kernel: ? ktime_get+0x3e/0xa0
+Jul 26 09:15:27 kernel: ? native_x2apic_icr_write+0x30/0x30
+Jul 26 09:15:27 kernel: run_timer_softirq+0x2a/0x50
+Jul 26 09:15:27 kernel: __do_softirq+0xd1/0x2c1
+Jul 26 09:15:27 kernel: irq_exit+0xae/0xb0
+Jul 26 09:15:27 kernel: smp_apic_timer_interrupt+0x7b/0x140
+Jul 26 09:15:27 kernel: apic_timer_interrupt+0xf/0x20
+Jul 26 09:15:27 kernel: </IRQ>
+Jul 26 09:15:27 kernel: RIP: 0010:native_safe_halt+0xe/0x10
+Jul 26 09:15:27 kernel: Code: 7b ff ff ff eb bd 90 90 90 90 90 90 e9 07 00 00 00 0f 00 2d 36 2c 50 00 f4 c3 66 90 e9 07 00 00 00 0f 00 2d 26 2c 50 00 fb f4 <c3> 90 0f 1f 44 00 00 55 48 89 e5 41 55 41 54 53 e8 dd 5e 61 ff 65
+Jul 26 09:15:27 kernel: RSP: 0018:ffffb783801cfe70 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff13
+Jul 26 09:15:27 kernel: RAX: ffffffffa6908b20 RBX: 0000000000000010 RCX: 0000000000000001
+Jul 26 09:15:27 kernel: RDX: 000000006fc0c97e RSI: 0000000000000082 RDI: 0000000000000082
+Jul 26 09:15:27 kernel: RBP: ffffb783801cfe90 R08: 0000000000000000 R09: 0000000000000225
+Jul 26 09:15:27 kernel: R10: 0000000000100000 R11: 0000000000000000 R12: 0000000000000010
+Jul 26 09:15:27 kernel: R13: ffff9b8e390b0000 R14: 0000000000000000 R15: 0000000000000000
+Jul 26 09:15:27 kernel: ? __cpuidle_text_start+0x8/0x8
+Jul 26 09:15:27 kernel: ? default_idle+0x20/0x140
+Jul 26 09:15:27 kernel: arch_cpu_idle+0x15/0x20
+Jul 26 09:15:27 kernel: default_idle_call+0x23/0x30
+Jul 26 09:15:27 kernel: do_idle+0x1fb/0x270
+Jul 26 09:15:27 kernel: cpu_startup_entry+0x20/0x30
+Jul 26 09:15:27 kernel: start_secondary+0x178/0x1d0
+Jul 26 09:15:27 kernel: secondary_startup_64+0xa4/0xb0
+Jul 26 09:15:27 kernel: ---[ end trace e7ac822987e33be1 ]---
+
+The NULL ptr deref is coming from tcp_rto_delta_us() attempting to pull an skb
+off the head of the retransmit queue and then dereferencing that skb to get the
+skb_mstamp_ns value via tcp_skb_timestamp_us(skb).
+
+The crash is the same one that was reported a # of years ago here:
+https://lore.kernel.org/netdev/86c0f836-9a7c-438b-d81a-839be45f1f58@gmail.com/T/#t
+
+and the kernel we're running has the fix which was added to resolve this issue.
+
+Unfortunately we've been unsuccessful so far in reproducing this problem in the
+lab and do not have the luxury of pushing out a new kernel to try and test if
+newer kernels resolve this issue at the moment. I realize this is a report
+against both an Ubuntu kernel and also an older 5.4 kernel. I have reported this
+issue to Ubuntu here: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2077657
+however I feel like since this issue has possibly cropped up again it makes
+sense to build in some protection in this path (even on the latest kernel
+versions) since the code in question just blindly assumes there's a valid skb
+without testing if it's NULL b/f it looks at the timestamp.
+
+Given we have seen crashes in this path before and now this case it seems like
+we should protect ourselves for when packets_out accounting is incorrect.
+While we should fix that root cause we should also just make sure the skb
+is not NULL before dereferencing it. Also add a warn once here to capture
+some information if/when the problem case is hit again.
+
+Fixes: e1a10ef7fa87 ("tcp: introduce tcp_rto_delta_us() helper for xmit timer fix")
+Signed-off-by: Josh Hunt <johunt@akamai.com>
+Acked-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/tcp.h | 21 +++++++++++++++++++--
+ 1 file changed, 19 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index 061e15a1ac87d..be91d81d66ab3 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -2123,9 +2123,26 @@ static inline s64 tcp_rto_delta_us(const struct sock *sk)
+ {
+ const struct sk_buff *skb = tcp_rtx_queue_head(sk);
+ u32 rto = inet_csk(sk)->icsk_rto;
+- u64 rto_time_stamp_us = tcp_skb_timestamp_us(skb) + jiffies_to_usecs(rto);
+
+- return rto_time_stamp_us - tcp_sk(sk)->tcp_mstamp;
++ if (likely(skb)) {
++ u64 rto_time_stamp_us = tcp_skb_timestamp_us(skb) + jiffies_to_usecs(rto);
++
++ return rto_time_stamp_us - tcp_sk(sk)->tcp_mstamp;
++ } else {
++ WARN_ONCE(1,
++ "rtx queue emtpy: "
++ "out:%u sacked:%u lost:%u retrans:%u "
++ "tlp_high_seq:%u sk_state:%u ca_state:%u "
++ "advmss:%u mss_cache:%u pmtu:%u\n",
++ tcp_sk(sk)->packets_out, tcp_sk(sk)->sacked_out,
++ tcp_sk(sk)->lost_out, tcp_sk(sk)->retrans_out,
++ tcp_sk(sk)->tlp_high_seq, sk->sk_state,
++ inet_csk(sk)->icsk_ca_state,
++ tcp_sk(sk)->advmss, tcp_sk(sk)->mss_cache,
++ inet_csk(sk)->icsk_pmtu_cookie);
++ return jiffies_to_usecs(rto);
++ }
++
+ }
+
+ /*
+--
+2.43.0
+
--- /dev/null
+From f3f3afce987827173b0d0dfc403b81d12c79b7d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Aug 2024 12:55:46 +0100
+Subject: tpm: Clean up TPM space after command failure
+
+From: Jonathan McDowell <noodles@meta.com>
+
+[ Upstream commit e3aaebcbb7c6b403416f442d1de70d437ce313a7 ]
+
+tpm_dev_transmit prepares the TPM space before attempting command
+transmission. However if the command fails no rollback of this
+preparation is done. This can result in transient handles being leaked
+if the device is subsequently closed with no further commands performed.
+
+Fix this by flushing the space in the event of command transmission
+failure.
+
+Fixes: 745b361e989a ("tpm: infrastructure for TPM spaces")
+Signed-off-by: Jonathan McDowell <noodles@meta.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-dev-common.c | 2 ++
+ drivers/char/tpm/tpm2-space.c | 3 +++
+ 2 files changed, 5 insertions(+)
+
+diff --git a/drivers/char/tpm/tpm-dev-common.c b/drivers/char/tpm/tpm-dev-common.c
+index dc4c0a0a51290..56e56a09cc905 100644
+--- a/drivers/char/tpm/tpm-dev-common.c
++++ b/drivers/char/tpm/tpm-dev-common.c
+@@ -47,6 +47,8 @@ static ssize_t tpm_dev_transmit(struct tpm_chip *chip, struct tpm_space *space,
+
+ if (!ret)
+ ret = tpm2_commit_space(chip, space, buf, &len);
++ else
++ tpm2_flush_space(chip);
+
+ out_rc:
+ return ret ? ret : len;
+diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c
+index ffb35f0154c16..c57404c6b98c9 100644
+--- a/drivers/char/tpm/tpm2-space.c
++++ b/drivers/char/tpm/tpm2-space.c
+@@ -166,6 +166,9 @@ void tpm2_flush_space(struct tpm_chip *chip)
+ struct tpm_space *space = &chip->work_space;
+ int i;
+
++ if (!space)
++ return;
++
+ for (i = 0; i < ARRAY_SIZE(space->context_tbl); i++)
+ if (space->context_tbl[i] && ~space->context_tbl[i])
+ tpm2_flush_context(chip, space->context_tbl[i]);
+--
+2.43.0
+
--- /dev/null
+From 0cbe715baf644398fb3b66f87afe2fb4729b59ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 Jul 2024 15:00:26 +0200
+Subject: usb: dwc2: Skip clock gating on Broadcom SoCs
+
+From: Stefan Wahren <wahrenst@gmx.net>
+
+[ Upstream commit d483f034f03261c8c8450d106aa243837122b5f0 ]
+
+On resume of the Raspberry Pi the dwc2 driver fails to enable
+HCD_FLAG_HW_ACCESSIBLE before re-enabling the interrupts.
+This causes a situation where both handler ignore a incoming port
+interrupt and force the upper layers to disable the dwc2 interrupt line.
+This leaves the USB interface in a unusable state:
+
+irq 66: nobody cared (try booting with the "irqpoll" option)
+CPU: 0 PID: 0 Comm: swapper/0 Tainted: G W 6.10.0-rc3
+Hardware name: BCM2835
+Call trace:
+unwind_backtrace from show_stack+0x10/0x14
+show_stack from dump_stack_lvl+0x50/0x64
+dump_stack_lvl from __report_bad_irq+0x38/0xc0
+__report_bad_irq from note_interrupt+0x2ac/0x2f4
+note_interrupt from handle_irq_event+0x88/0x8c
+handle_irq_event from handle_level_irq+0xb4/0x1ac
+handle_level_irq from generic_handle_domain_irq+0x24/0x34
+generic_handle_domain_irq from bcm2836_chained_handle_irq+0x24/0x28
+bcm2836_chained_handle_irq from generic_handle_domain_irq+0x24/0x34
+generic_handle_domain_irq from generic_handle_arch_irq+0x34/0x44
+generic_handle_arch_irq from __irq_svc+0x88/0xb0
+Exception stack(0xc1b01f20 to 0xc1b01f68)
+1f20: 0005c0d4 00000001 00000000 00000000 c1b09780 c1d6b32c c1b04e54 c1a5eae8
+1f40: c1b04e90 00000000 00000000 00000000 c1d6a8a0 c1b01f70 c11d2da8 c11d4160
+1f60: 60000013 ffffffff
+__irq_svc from default_idle_call+0x1c/0xb0
+default_idle_call from do_idle+0x21c/0x284
+do_idle from cpu_startup_entry+0x28/0x2c
+cpu_startup_entry from kernel_init+0x0/0x12c
+handlers:
+[<f539e0f4>] dwc2_handle_common_intr
+[<75cd278b>] usb_hcd_irq
+Disabling IRQ #66
+
+Disabling clock gating workaround this issue.
+
+Fixes: 0112b7ce68ea ("usb: dwc2: Update dwc2_handle_usb_suspend_intr function.")
+Link: https://lore.kernel.org/linux-usb/3fd0c2fb-4752-45b3-94eb-42352703e1fd@gmx.net/T/
+Link: https://lore.kernel.org/all/5e8cbce0-3260-2971-484f-fc73a3b2bd28@synopsys.com/
+Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
+Acked-by: Minas Harutyunyan <hminas@synopsys.com>
+Link: https://lore.kernel.org/r/20240728130029.78279-5-wahrenst@gmx.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc2/params.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c
+index 59e1193459947..90b68964f143c 100644
+--- a/drivers/usb/dwc2/params.c
++++ b/drivers/usb/dwc2/params.c
+@@ -47,6 +47,7 @@ static void dwc2_set_bcm_params(struct dwc2_hsotg *hsotg)
+ p->max_transfer_size = 65535;
+ p->max_packet_count = 511;
+ p->ahbcfg = 0x10;
++ p->no_clock_gating = true;
+ }
+
+ static void dwc2_set_his_params(struct dwc2_hsotg *hsotg)
+--
+2.43.0
+
--- /dev/null
+From e8dfafdd07d0962985a220cccd6aeb9714f465de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Mar 2023 13:30:40 +0800
+Subject: vdpa: Add eventfd for the vdpa callback
+
+From: Xie Yongji <xieyongji@bytedance.com>
+
+[ Upstream commit 5e68470f4e80a4120e9ecec408f6ab4ad386bd4a ]
+
+Add eventfd for the vdpa callback so that user
+can signal it directly instead of triggering the
+callback. It will be used for vhost-vdpa case.
+
+Signed-off-by: Xie Yongji <xieyongji@bytedance.com>
+Message-Id: <20230323053043.35-9-xieyongji@bytedance.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Stable-dep-of: 02e9e9366fef ("vhost_vdpa: assign irq bypass producer token correctly")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vhost/vdpa.c | 2 ++
+ drivers/virtio/virtio_vdpa.c | 1 +
+ include/linux/vdpa.h | 6 ++++++
+ 3 files changed, 9 insertions(+)
+
+diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
+index 019e8c9bedffb..1dc11ba0922d2 100644
+--- a/drivers/vhost/vdpa.c
++++ b/drivers/vhost/vdpa.c
+@@ -432,9 +432,11 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
+ if (vq->call_ctx.ctx) {
+ cb.callback = vhost_vdpa_virtqueue_cb;
+ cb.private = vq;
++ cb.trigger = vq->call_ctx.ctx;
+ } else {
+ cb.callback = NULL;
+ cb.private = NULL;
++ cb.trigger = NULL;
+ }
+ ops->set_vq_cb(vdpa, idx, &cb);
+ vhost_vdpa_setup_vq_irq(v, idx);
+diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c
+index 72eaef2caeb14..1c29446aafb44 100644
+--- a/drivers/virtio/virtio_vdpa.c
++++ b/drivers/virtio/virtio_vdpa.c
+@@ -182,6 +182,7 @@ virtio_vdpa_setup_vq(struct virtio_device *vdev, unsigned int index,
+ /* Setup virtqueue callback */
+ cb.callback = virtio_vdpa_virtqueue_cb;
+ cb.private = info;
++ cb.trigger = NULL;
+ ops->set_vq_cb(vdpa, index, &cb);
+ ops->set_vq_num(vdpa, index, virtqueue_get_vring_size(vq));
+
+diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h
+index 3972ab765de18..4fb198c8dbf61 100644
+--- a/include/linux/vdpa.h
++++ b/include/linux/vdpa.h
+@@ -11,10 +11,16 @@
+ * struct vdpa_calllback - vDPA callback definition.
+ * @callback: interrupt callback function
+ * @private: the data passed to the callback function
++ * @trigger: the eventfd for the callback (Optional).
++ * When it is set, the vDPA driver must guarantee that
++ * signaling it is functional equivalent to triggering
++ * the callback. Then vDPA parent can signal it directly
++ * instead of triggering the callback.
+ */
+ struct vdpa_callback {
+ irqreturn_t (*callback)(void *data);
+ void *private;
++ struct eventfd_ctx *trigger;
+ };
+
+ /**
+--
+2.43.0
+
--- /dev/null
+From 622039b4c46fcf273c217e6783db9672a4bd4aef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Aug 2024 11:19:00 +0800
+Subject: vhost_vdpa: assign irq bypass producer token correctly
+
+From: Jason Wang <jasowang@redhat.com>
+
+[ Upstream commit 02e9e9366fefe461719da5d173385b6685f70319 ]
+
+We used to call irq_bypass_unregister_producer() in
+vhost_vdpa_setup_vq_irq() which is problematic as we don't know if the
+token pointer is still valid or not.
+
+Actually, we use the eventfd_ctx as the token so the life cycle of the
+token should be bound to the VHOST_SET_VRING_CALL instead of
+vhost_vdpa_setup_vq_irq() which could be called by set_status().
+
+Fixing this by setting up irq bypass producer's token when handling
+VHOST_SET_VRING_CALL and un-registering the producer before calling
+vhost_vring_ioctl() to prevent a possible use after free as eventfd
+could have been released in vhost_vring_ioctl(). And such registering
+and unregistering will only be done if DRIVER_OK is set.
+
+Reported-by: Dragos Tatulea <dtatulea@nvidia.com>
+Tested-by: Dragos Tatulea <dtatulea@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Fixes: 2cf1ba9a4d15 ("vhost_vdpa: implement IRQ offloading in vhost_vdpa")
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Message-Id: <20240816031900.18013-1-jasowang@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vhost/vdpa.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
+index 1dc11ba0922d2..58ba684037f9e 100644
+--- a/drivers/vhost/vdpa.c
++++ b/drivers/vhost/vdpa.c
+@@ -100,11 +100,9 @@ static void vhost_vdpa_setup_vq_irq(struct vhost_vdpa *v, u16 qid)
+ if (irq < 0)
+ return;
+
+- irq_bypass_unregister_producer(&vq->call_ctx.producer);
+ if (!vq->call_ctx.ctx)
+ return;
+
+- vq->call_ctx.producer.token = vq->call_ctx.ctx;
+ vq->call_ctx.producer.irq = irq;
+ ret = irq_bypass_register_producer(&vq->call_ctx.producer);
+ if (unlikely(ret))
+@@ -401,6 +399,14 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
+ vq->last_avail_idx = vq_state.split.avail_index;
+ }
+ break;
++ case VHOST_SET_VRING_CALL:
++ if (vq->call_ctx.ctx) {
++ if (ops->get_status(vdpa) &
++ VIRTIO_CONFIG_S_DRIVER_OK)
++ vhost_vdpa_unsetup_vq_irq(v, idx);
++ vq->call_ctx.producer.token = NULL;
++ }
++ break;
+ }
+
+ r = vhost_vring_ioctl(&v->vdev, cmd, argp);
+@@ -433,13 +439,16 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
+ cb.callback = vhost_vdpa_virtqueue_cb;
+ cb.private = vq;
+ cb.trigger = vq->call_ctx.ctx;
++ vq->call_ctx.producer.token = vq->call_ctx.ctx;
++ if (ops->get_status(vdpa) &
++ VIRTIO_CONFIG_S_DRIVER_OK)
++ vhost_vdpa_setup_vq_irq(v, idx);
+ } else {
+ cb.callback = NULL;
+ cb.private = NULL;
+ cb.trigger = NULL;
+ }
+ ops->set_vq_cb(vdpa, idx, &cb);
+- vhost_vdpa_setup_vq_irq(v, idx);
+ break;
+
+ case VHOST_SET_VRING_NUM:
+@@ -990,6 +999,7 @@ static int vhost_vdpa_open(struct inode *inode, struct file *filep)
+ for (i = 0; i < nvqs; i++) {
+ vqs[i] = &v->vqs[i];
+ vqs[i]->handle_kick = handle_vq_kick;
++ vqs[i]->call_ctx.ctx = NULL;
+ }
+ vhost_dev_init(dev, vqs, nvqs, 0, 0, 0, false,
+ vhost_vdpa_process_iotlb_msg);
+--
+2.43.0
+
--- /dev/null
+From 45d73a1b4c1fa6e27ed39c2c98d1da4a95d4fd3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Aug 2024 14:18:45 +0200
+Subject: watchdog: imx_sc_wdt: Don't disable WDT in suspend
+
+From: Jonas Blixt <jonas.blixt@actia.se>
+
+[ Upstream commit 2d9d6d300fb0a4ae4431bb308027ac9385746d42 ]
+
+Parts of the suspend and resume chain is left unprotected if we disable
+the WDT here.
+
+>From experiments we can see that the SCU disables and re-enables the WDT
+when we enter and leave suspend to ram. By not touching the WDT here we
+are protected by the WDT all the way to the SCU.
+
+Signed-off-by: Jonas Blixt <jonas.blixt@actia.se>
+CC: Anson Huang <anson.huang@nxp.com>
+Fixes: 986857acbc9a ("watchdog: imx_sc: Add i.MX system controller watchdog support")
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20240801121845.1465765-1-jonas.blixt@actia.se
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/imx_sc_wdt.c | 24 ------------------------
+ 1 file changed, 24 deletions(-)
+
+diff --git a/drivers/watchdog/imx_sc_wdt.c b/drivers/watchdog/imx_sc_wdt.c
+index 8ac021748d160..79649b0e89e47 100644
+--- a/drivers/watchdog/imx_sc_wdt.c
++++ b/drivers/watchdog/imx_sc_wdt.c
+@@ -213,29 +213,6 @@ static int imx_sc_wdt_probe(struct platform_device *pdev)
+ return devm_watchdog_register_device(dev, wdog);
+ }
+
+-static int __maybe_unused imx_sc_wdt_suspend(struct device *dev)
+-{
+- struct imx_sc_wdt_device *imx_sc_wdd = dev_get_drvdata(dev);
+-
+- if (watchdog_active(&imx_sc_wdd->wdd))
+- imx_sc_wdt_stop(&imx_sc_wdd->wdd);
+-
+- return 0;
+-}
+-
+-static int __maybe_unused imx_sc_wdt_resume(struct device *dev)
+-{
+- struct imx_sc_wdt_device *imx_sc_wdd = dev_get_drvdata(dev);
+-
+- if (watchdog_active(&imx_sc_wdd->wdd))
+- imx_sc_wdt_start(&imx_sc_wdd->wdd);
+-
+- return 0;
+-}
+-
+-static SIMPLE_DEV_PM_OPS(imx_sc_wdt_pm_ops,
+- imx_sc_wdt_suspend, imx_sc_wdt_resume);
+-
+ static const struct of_device_id imx_sc_wdt_dt_ids[] = {
+ { .compatible = "fsl,imx-sc-wdt", },
+ { /* sentinel */ }
+@@ -247,7 +224,6 @@ static struct platform_driver imx_sc_wdt_driver = {
+ .driver = {
+ .name = "imx-sc-wdt",
+ .of_match_table = imx_sc_wdt_dt_ids,
+- .pm = &imx_sc_wdt_pm_ops,
+ },
+ };
+ module_platform_driver(imx_sc_wdt_driver);
+--
+2.43.0
+
--- /dev/null
+From 70796edc6fe21822ca335d49aaa6f6d37b49d6b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jul 2023 19:47:40 +0800
+Subject: wifi: ath9k: fix parameter check in ath9k_init_debug()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Minjie Du <duminjie@vivo.com>
+
+[ Upstream commit 6edb4ba6fb5b946d112259f54f4657f82eb71e89 ]
+
+Make IS_ERR() judge the debugfs_create_dir() function return
+in ath9k_init_debug()
+
+Signed-off-by: Minjie Du <duminjie@vivo.com>
+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/20230712114740.13226-1-duminjie@vivo.com
+Stable-dep-of: f6ffe7f01847 ("wifi: ath9k: Remove error checks when creating debugfs entries")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/debug.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
+index 6a043a49dfe6f..4badc4c453f3a 100644
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -1371,7 +1371,7 @@ int ath9k_init_debug(struct ath_hw *ah)
+
+ sc->debug.debugfs_phy = debugfs_create_dir("ath9k",
+ sc->hw->wiphy->debugfsdir);
+- if (!sc->debug.debugfs_phy)
++ if (IS_ERR(sc->debug.debugfs_phy))
+ return -ENOMEM;
+
+ #ifdef CONFIG_ATH_DEBUG
+--
+2.43.0
+
--- /dev/null
+From abcf05b6ce47c5af2bdd7ae1c0c1be74ede0278a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Aug 2024 13:02:22 +0200
+Subject: wifi: ath9k: Remove error checks when creating debugfs entries
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Toke Høiland-Jørgensen <toke@redhat.com>
+
+[ Upstream commit f6ffe7f0184792c2f99aca6ae5b916683973d7d3 ]
+
+We should not be checking the return values from debugfs creation at all: the
+debugfs functions are designed to handle errors of previously called functions
+and just transparently abort the creation of debugfs entries when debugfs is
+disabled. If we check the return value and abort driver initialisation, we break
+the driver if debugfs is disabled (such as when booting with debugfs=off).
+
+Earlier versions of ath9k accidentally did the right thing by checking the
+return value, but only for NULL, not for IS_ERR(). This was "fixed" by the two
+commits referenced below, breaking ath9k with debugfs=off starting from the 6.6
+kernel (as reported in the Bugzilla linked below).
+
+Restore functionality by just getting rid of the return value check entirely.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=219122
+Fixes: 1e4134610d93 ("wifi: ath9k: use IS_ERR() with debugfs_create_dir()")
+Fixes: 6edb4ba6fb5b ("wifi: ath9k: fix parameter check in ath9k_init_debug()")
+Reported-by: Daniel Tobias <dan.g.tob@gmail.com>
+Tested-by: Daniel Tobias <dan.g.tob@gmail.com>
+Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
+Link: https://patch.msgid.link/20240805110225.19690-1-toke@toke.dk
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/debug.c | 2 --
+ drivers/net/wireless/ath/ath9k/htc_drv_debug.c | 2 --
+ 2 files changed, 4 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
+index 4badc4c453f3a..f6f63923966af 100644
+--- a/drivers/net/wireless/ath/ath9k/debug.c
++++ b/drivers/net/wireless/ath/ath9k/debug.c
+@@ -1371,8 +1371,6 @@ int ath9k_init_debug(struct ath_hw *ah)
+
+ sc->debug.debugfs_phy = debugfs_create_dir("ath9k",
+ sc->hw->wiphy->debugfsdir);
+- if (IS_ERR(sc->debug.debugfs_phy))
+- return -ENOMEM;
+
+ #ifdef CONFIG_ATH_DEBUG
+ debugfs_create_file("debug", 0600, sc->debug.debugfs_phy,
+diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+index e79bbcd3279af..81332086e2899 100644
+--- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
++++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+@@ -491,8 +491,6 @@ int ath9k_htc_init_debug(struct ath_hw *ah)
+
+ priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME,
+ priv->hw->wiphy->debugfsdir);
+- if (IS_ERR(priv->debug.debugfs_phy))
+- return -ENOMEM;
+
+ ath9k_cmn_spectral_init_debug(&priv->spec_priv, priv->debug.debugfs_phy);
+
+--
+2.43.0
+
--- /dev/null
+From e4d358735565e109e599ffd1bebf49bf5559156d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Sep 2024 12:08:06 +0300
+Subject: wifi: cfg80211: fix two more possible UBSAN-detected off-by-one
+ errors
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 15ea13b1b1fbf6364d4cd568e65e4c8479632999 ]
+
+Although not reproduced in practice, these two cases may be
+considered by UBSAN as off-by-one errors. So fix them in the
+same way as in commit a26a5107bc52 ("wifi: cfg80211: fix UBSAN
+noise in cfg80211_wext_siwscan()").
+
+Fixes: 807f8a8c3004 ("cfg80211/nl80211: add support for scheduled scans")
+Fixes: 5ba63533bbf6 ("cfg80211: fix alignment problem in scan request")
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Link: https://patch.msgid.link/20240909090806.1091956-1-dmantipov@yandex.ru
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 3 ++-
+ net/wireless/sme.c | 3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index a46278cf67da9..d286a10f35522 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -8784,7 +8784,8 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
+ return ERR_PTR(-ENOMEM);
+
+ if (n_ssids)
+- request->ssids = (void *)&request->channels[n_channels];
++ request->ssids = (void *)request +
++ struct_size(request, channels, n_channels);
+ request->n_ssids = n_ssids;
+ if (ie_len) {
+ if (n_ssids)
+diff --git a/net/wireless/sme.c b/net/wireless/sme.c
+index 1591cd68fc583..3c29e9bf66b4e 100644
+--- a/net/wireless/sme.c
++++ b/net/wireless/sme.c
+@@ -115,7 +115,8 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
+ n_channels = i;
+ }
+ request->n_channels = n_channels;
+- request->ssids = (void *)&request->channels[n_channels];
++ request->ssids = (void *)request +
++ struct_size(request, channels, n_channels);
+ request->n_ssids = 1;
+
+ memcpy(request->ssids[0].ssid, wdev->conn->params.ssid,
+--
+2.43.0
+
--- /dev/null
+From 06cfc01ead4719856e01190f038315d39ea5d6b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Sep 2024 18:04:00 +0300
+Subject: wifi: cfg80211: fix UBSAN noise in cfg80211_wext_siwscan()
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit a26a5107bc52922cf5f67361e307ad66547b51c7 ]
+
+Looking at https://syzkaller.appspot.com/bug?extid=1a3986bbd3169c307819
+and running reproducer with CONFIG_UBSAN_BOUNDS, I've noticed the
+following:
+
+[ T4985] UBSAN: array-index-out-of-bounds in net/wireless/scan.c:3479:25
+[ T4985] index 164 is out of range for type 'struct ieee80211_channel *[]'
+<...skipped...>
+[ T4985] Call Trace:
+[ T4985] <TASK>
+[ T4985] dump_stack_lvl+0x1c2/0x2a0
+[ T4985] ? __pfx_dump_stack_lvl+0x10/0x10
+[ T4985] ? __pfx__printk+0x10/0x10
+[ T4985] __ubsan_handle_out_of_bounds+0x127/0x150
+[ T4985] cfg80211_wext_siwscan+0x11a4/0x1260
+<...the rest is not too useful...>
+
+Even if we do 'creq->n_channels = n_channels' before 'creq->ssids =
+(void *)&creq->channels[n_channels]', UBSAN treats the latter as
+off-by-one error. Fix this by using pointer arithmetic rather than
+an expression with explicit array indexing and use convenient
+'struct_size()' to simplify the math here and in 'kzalloc()' above.
+
+Fixes: 5ba63533bbf6 ("cfg80211: fix alignment problem in scan request")
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Reviewed-by: Kees Cook <kees@kernel.org>
+Link: https://patch.msgid.link/20240905150400.126386-1-dmantipov@yandex.ru
+[fix coding style for multi-line calculation]
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/scan.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index b8e28025710dd..dc41b31073e75 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -2813,8 +2813,8 @@ int cfg80211_wext_siwscan(struct net_device *dev,
+ n_channels = ieee80211_get_num_supported_channels(wiphy);
+ }
+
+- creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
+- n_channels * sizeof(void *),
++ creq = kzalloc(struct_size(creq, channels, n_channels) +
++ sizeof(struct cfg80211_ssid),
+ GFP_ATOMIC);
+ if (!creq) {
+ err = -ENOMEM;
+@@ -2824,7 +2824,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
+ creq->wiphy = wiphy;
+ creq->wdev = dev->ieee80211_ptr;
+ /* SSIDs come after channels */
+- creq->ssids = (void *)&creq->channels[n_channels];
++ creq->ssids = (void *)creq + struct_size(creq, channels, n_channels);
+ creq->n_channels = n_channels;
+ creq->n_ssids = 1;
+ creq->scan_start = jiffies;
+--
+2.43.0
+
--- /dev/null
+From 8dcadb66343931dc8c11db360e5f12f694beae3d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Jul 2024 20:20:12 +0300
+Subject: wifi: iwlwifi: mvm: increase the time between ranging measurements
+
+From: Avraham Stern <avraham.stern@intel.com>
+
+[ Upstream commit 3a7ee94559dfd640604d0265739e86dec73b64e8 ]
+
+The algo running in fw may take a little longer than 5 milliseconds,
+(e.g. measurement on 80MHz while associated). Increase the minimum
+time between measurements to 7 milliseconds.
+
+Fixes: 830aa3e7d1ca ("iwlwifi: mvm: add support for range request command version 13")
+Signed-off-by: Avraham Stern <avraham.stern@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20240729201718.d3f3c26e00d9.I09e951290e8a3d73f147b88166fd9a678d1d69ed@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/constants.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
+index 9d0d01f27d929..36042c334a13d 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
+@@ -103,7 +103,7 @@
+ #define IWL_MVM_FTM_INITIATOR_SECURE_LTF false
+ #define IWL_MVM_FTM_RESP_NDP_SUPPORT true
+ #define IWL_MVM_FTM_RESP_LMR_FEEDBACK_SUPPORT true
+-#define IWL_MVM_FTM_NON_TB_MIN_TIME_BETWEEN_MSR 5
++#define IWL_MVM_FTM_NON_TB_MIN_TIME_BETWEEN_MSR 7
+ #define IWL_MVM_FTM_NON_TB_MAX_TIME_BETWEEN_MSR 1000
+ #define IWL_MVM_D3_DEBUG false
+ #define IWL_MVM_USE_TWT true
+--
+2.43.0
+
--- /dev/null
+From 001db3690597e60153aa6d33e02d360cf682664b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Sep 2024 15:31:51 +0300
+Subject: wifi: mac80211: use two-phase skb reclamation in ieee80211_do_stop()
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 9d301de12da6e1bb069a9835c38359b8e8135121 ]
+
+Since '__dev_queue_xmit()' should be called with interrupts enabled,
+the following backtrace:
+
+ieee80211_do_stop()
+ ...
+ spin_lock_irqsave(&local->queue_stop_reason_lock, flags)
+ ...
+ ieee80211_free_txskb()
+ ieee80211_report_used_skb()
+ ieee80211_report_ack_skb()
+ cfg80211_mgmt_tx_status_ext()
+ nl80211_frame_tx_status()
+ genlmsg_multicast_netns()
+ genlmsg_multicast_netns_filtered()
+ nlmsg_multicast_filtered()
+ netlink_broadcast_filtered()
+ do_one_broadcast()
+ netlink_broadcast_deliver()
+ __netlink_sendskb()
+ netlink_deliver_tap()
+ __netlink_deliver_tap_skb()
+ dev_queue_xmit()
+ __dev_queue_xmit() ; with IRQS disabled
+ ...
+ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags)
+
+issues the warning (as reported by syzbot reproducer):
+
+WARNING: CPU: 2 PID: 5128 at kernel/softirq.c:362 __local_bh_enable_ip+0xc3/0x120
+
+Fix this by implementing a two-phase skb reclamation in
+'ieee80211_do_stop()', where actual work is performed
+outside of a section with interrupts disabled.
+
+Fixes: 5061b0c2b906 ("mac80211: cooperate more with network namespaces")
+Reported-by: syzbot+1a3986bbd3169c307819@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=1a3986bbd3169c307819
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Link: https://patch.msgid.link/20240906123151.351647-1-dmantipov@yandex.ru
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mac80211/iface.c | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index 041859b5b71d0..e362a08af2873 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -369,6 +369,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ {
+ struct ieee80211_local *local = sdata->local;
+ unsigned long flags;
++ struct sk_buff_head freeq;
+ struct sk_buff *skb, *tmp;
+ u32 hw_reconf_flags = 0;
+ int i, flushed;
+@@ -555,18 +556,32 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
+ skb_queue_purge(&sdata->status_queue);
+ }
+
++ /*
++ * Since ieee80211_free_txskb() may issue __dev_queue_xmit()
++ * which should be called with interrupts enabled, reclamation
++ * is done in two phases:
++ */
++ __skb_queue_head_init(&freeq);
++
++ /* unlink from local queues... */
+ spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
+ for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
+ skb_queue_walk_safe(&local->pending[i], skb, tmp) {
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ if (info->control.vif == &sdata->vif) {
+ __skb_unlink(skb, &local->pending[i]);
+- ieee80211_free_txskb(&local->hw, skb);
++ __skb_queue_tail(&freeq, skb);
+ }
+ }
+ }
+ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+
++ /* ... and perform actual reclamation with interrupts enabled. */
++ skb_queue_walk_safe(&freeq, skb, tmp) {
++ __skb_unlink(skb, &freeq);
++ ieee80211_free_txskb(&local->hw, skb);
++ }
++
+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+ ieee80211_txq_remove_vlan(local, sdata);
+
+--
+2.43.0
+
--- /dev/null
+From ade8b33bfc7fe241f7ea2c22be312c8a69c39ca2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Aug 2024 11:30:08 +0200
+Subject: wifi: mt76: mt7915: fix rx filter setting for bfee functionality
+
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+
+[ Upstream commit 6ac80fce713e875a316a58975b830720a3e27721 ]
+
+Fix rx filter setting to prevent dropping NDPA frames. Without this
+change, bfee functionality may behave abnormally.
+
+Fixes: e57b7901469f ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets")
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+Link: https://patch.msgid.link/20240827093011.18621-21-nbd@nbd.name
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/mediatek/mt76/mt7915/main.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+index 09ea97a81fb4f..6e8ad657c65d8 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+@@ -526,8 +526,7 @@ static void mt7915_configure_filter(struct ieee80211_hw *hw,
+
+ MT76_FILTER(CONTROL, MT_WF_RFCR_DROP_CTS |
+ MT_WF_RFCR_DROP_RTS |
+- MT_WF_RFCR_DROP_CTL_RSV |
+- MT_WF_RFCR_DROP_NDPA);
++ MT_WF_RFCR_DROP_CTL_RSV);
+
+ *total_flags = flags;
+ mt76_wr(dev, MT_WF_RFCR(band), phy->rxfilter);
+--
+2.43.0
+
--- /dev/null
+From 1b229bea532a9c6b331d3fc3c914f4b930e7a678 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Jul 2024 14:46:57 +0300
+Subject: wifi: rtw88: always wait for both firmware loading attempts
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 0e735a4c6137262bcefe45bb52fde7b1f5fc6c4d ]
+
+In 'rtw_wait_firmware_completion()', always wait for both (regular and
+wowlan) firmware loading attempts. Otherwise if 'rtw_usb_intf_init()'
+has failed in 'rtw_usb_probe()', 'rtw_usb_disconnect()' may issue
+'ieee80211_free_hw()' when one of 'rtw_load_firmware_cb()' (usually
+the wowlan one) is still in progress, causing UAF detected by KASAN.
+
+Fixes: c8e5695eae99 ("rtw88: load wowlan firmware if wowlan is supported")
+Reported-by: syzbot+6c6c08700f9480c41fe3@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=6c6c08700f9480c41fe3
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/20240726114657.25396-1-dmantipov@yandex.ru
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/main.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
+index d7b7b2cce9746..23971a5737cf5 100644
+--- a/drivers/net/wireless/realtek/rtw88/main.c
++++ b/drivers/net/wireless/realtek/rtw88/main.c
+@@ -1153,20 +1153,21 @@ static int rtw_wait_firmware_completion(struct rtw_dev *rtwdev)
+ {
+ struct rtw_chip_info *chip = rtwdev->chip;
+ struct rtw_fw_state *fw;
++ int ret = 0;
+
+ fw = &rtwdev->fw;
+ wait_for_completion(&fw->completion);
+ if (!fw->firmware)
+- return -EINVAL;
++ ret = -EINVAL;
+
+ if (chip->wow_fw_name) {
+ fw = &rtwdev->wow_fw;
+ wait_for_completion(&fw->completion);
+ if (!fw->firmware)
+- return -EINVAL;
++ ret = -EINVAL;
+ }
+
+- return 0;
++ return ret;
+ }
+
+ static enum rtw_lps_deep_mode rtw_update_lps_deep_mode(struct rtw_dev *rtwdev,
+--
+2.43.0
+
--- /dev/null
+From 4fd3c46aa738dae32d70e40015ec5d472f10073b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Aug 2024 11:53:10 +0300
+Subject: wifi: rtw88: remove CPT execution branch never used
+
+From: Dmitry Kandybka <d.kandybka@gmail.com>
+
+[ Upstream commit 77c977327dfaa9ae2e154964cdb89ceb5c7b7cf1 ]
+
+In 'rtw_coex_action_bt_a2dp_pan', 'wl_cpt_test' and 'bt_cpt_test' are
+hardcoded to false, so corresponding 'table_case' and 'tdma_case'
+assignments are never met.
+Also 'rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[1])' is never
+executed. Assuming that CPT was never fully implemented, remove
+lookalike leftovers. Compile tested only.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 76f631cb401f ("rtw88: coex: update the mechanism for A2DP + PAN")
+
+Signed-off-by: Dmitry Kandybka <d.kandybka@gmail.com>
+Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
+Link: https://patch.msgid.link/20240809085310.10512-1-d.kandybka@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/realtek/rtw88/coex.c | 38 ++++++-----------------
+ 1 file changed, 10 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/net/wireless/realtek/rtw88/coex.c b/drivers/net/wireless/realtek/rtw88/coex.c
+index 2551e228b5819..347fc36068edb 100644
+--- a/drivers/net/wireless/realtek/rtw88/coex.c
++++ b/drivers/net/wireless/realtek/rtw88/coex.c
+@@ -2103,7 +2103,6 @@ static void rtw_coex_action_bt_a2dp_pan(struct rtw_dev *rtwdev)
+ struct rtw_efuse *efuse = &rtwdev->efuse;
+ struct rtw_chip_info *chip = rtwdev->chip;
+ u8 table_case, tdma_case;
+- bool wl_cpt_test = false, bt_cpt_test = false;
+
+ rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
+
+@@ -2111,29 +2110,16 @@ static void rtw_coex_action_bt_a2dp_pan(struct rtw_dev *rtwdev)
+ rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
+ if (efuse->share_ant) {
+ /* Shared-Ant */
+- if (wl_cpt_test) {
+- if (coex_stat->wl_gl_busy) {
+- table_case = 20;
+- tdma_case = 17;
+- } else {
+- table_case = 10;
+- tdma_case = 15;
+- }
+- } else if (bt_cpt_test) {
+- table_case = 26;
+- tdma_case = 26;
+- } else {
+- if (coex_stat->wl_gl_busy &&
+- coex_stat->wl_noisy_level == 0)
+- table_case = 14;
+- else
+- table_case = 10;
++ if (coex_stat->wl_gl_busy &&
++ coex_stat->wl_noisy_level == 0)
++ table_case = 14;
++ else
++ table_case = 10;
+
+- if (coex_stat->wl_gl_busy)
+- tdma_case = 15;
+- else
+- tdma_case = 20;
+- }
++ if (coex_stat->wl_gl_busy)
++ tdma_case = 15;
++ else
++ tdma_case = 20;
+ } else {
+ /* Non-Shared-Ant */
+ table_case = 112;
+@@ -2144,11 +2130,7 @@ static void rtw_coex_action_bt_a2dp_pan(struct rtw_dev *rtwdev)
+ tdma_case = 120;
+ }
+
+- if (wl_cpt_test)
+- rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[1]);
+- else
+- rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
+-
++ rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
+ rtw_coex_table(rtwdev, false, table_case);
+ rtw_coex_tdma(rtwdev, false, tdma_case);
+ }
+--
+2.43.0
+
--- /dev/null
+From 63aea835682841edf5091ab7442450b6a01f32ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Aug 2024 08:17:09 +0000
+Subject: wifi: wilc1000: fix potential RCU dereference issue in
+ wilc_parse_join_bss_param
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jiawei Ye <jiawei.ye@foxmail.com>
+
+[ Upstream commit 6d7c6ae1efb1ff68bc01d79d94fdf0388f86cdd8 ]
+
+In the `wilc_parse_join_bss_param` function, the TSF field of the `ies`
+structure is accessed after the RCU read-side critical section is
+unlocked. According to RCU usage rules, this is illegal. Reusing this
+pointer can lead to unpredictable behavior, including accessing memory
+that has been updated or causing use-after-free issues.
+
+This possible bug was identified using a static analysis tool developed
+by myself, specifically designed to detect RCU-related issues.
+
+To address this, the TSF value is now stored in a local variable
+`ies_tsf` before the RCU lock is released. The `param->tsf_lo` field is
+then assigned using this local variable, ensuring that the TSF value is
+safely accessed.
+
+Fixes: 205c50306acf ("wifi: wilc1000: fix RCU usage in connect path")
+Signed-off-by: Jiawei Ye <jiawei.ye@foxmail.com>
+Reviewed-by: Alexis Lothoré <alexis.lothore@bootlin.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://patch.msgid.link/tencent_466225AA599BA49627FB26F707EE17BC5407@qq.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/microchip/wilc1000/hif.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/microchip/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c
+index 3d6877acff3a0..bfeb4287f08af 100644
+--- a/drivers/net/wireless/microchip/wilc1000/hif.c
++++ b/drivers/net/wireless/microchip/wilc1000/hif.c
+@@ -366,6 +366,7 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
+ struct wilc_join_bss_param *param;
+ u8 rates_len = 0;
+ int ies_len;
++ u64 ies_tsf;
+ int ret;
+
+ param = kzalloc(sizeof(*param), GFP_KERNEL);
+@@ -381,6 +382,7 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
+ return NULL;
+ }
+ ies_len = ies->len;
++ ies_tsf = ies->tsf;
+ rcu_read_unlock();
+
+ param->beacon_period = cpu_to_le16(bss->beacon_interval);
+@@ -436,7 +438,7 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
+ IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
+ (u8 *)&noa_attr, sizeof(noa_attr));
+ if (ret > 0) {
+- param->tsf_lo = cpu_to_le32(ies->tsf);
++ param->tsf_lo = cpu_to_le32(ies_tsf);
+ param->noa_enabled = 1;
+ param->idx = noa_attr.index;
+ if (noa_attr.oppps_ctwindow & IEEE80211_P2P_OPPPS_ENABLE_BIT) {
+--
+2.43.0
+
--- /dev/null
+From 8d468b91298b4f3a4d0aecf0b84d6cee726a3699 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Sep 2024 16:08:54 +0800
+Subject: x86/sgx: Fix deadlock in SGX NUMA node search
+
+From: Aaron Lu <aaron.lu@intel.com>
+
+[ Upstream commit 9c936844010466535bd46ea4ce4656ef17653644 ]
+
+When the current node doesn't have an EPC section configured by firmware
+and all other EPC sections are used up, CPU can get stuck inside the
+while loop that looks for an available EPC page from remote nodes
+indefinitely, leading to a soft lockup. Note how nid_of_current will
+never be equal to nid in that while loop because nid_of_current is not
+set in sgx_numa_mask.
+
+Also worth mentioning is that it's perfectly fine for the firmware not
+to setup an EPC section on a node. While setting up an EPC section on
+each node can enhance performance, it is not a requirement for
+functionality.
+
+Rework the loop to start and end on *a* node that has SGX memory. This
+avoids the deadlock looking for the current SGX-lacking node to show up
+in the loop when it never will.
+
+Fixes: 901ddbb9ecf5 ("x86/sgx: Add a basic NUMA allocation scheme to sgx_alloc_epc_page()")
+Reported-by: "Molina Sabido, Gerardo" <gerardo.molina.sabido@intel.com>
+Signed-off-by: Aaron Lu <aaron.lu@intel.com>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Reviewed-by: Kai Huang <kai.huang@intel.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
+Tested-by: Zhimin Luo <zhimin.luo@intel.com>
+Link: https://lore.kernel.org/all/20240905080855.1699814-2-aaron.lu%40intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/sgx/main.c | 27 ++++++++++++++-------------
+ 1 file changed, 14 insertions(+), 13 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
+index 4ea48acf55faa..ad453b4387a44 100644
+--- a/arch/x86/kernel/cpu/sgx/main.c
++++ b/arch/x86/kernel/cpu/sgx/main.c
+@@ -505,24 +505,25 @@ struct sgx_epc_page *__sgx_alloc_epc_page(void)
+ {
+ struct sgx_epc_page *page;
+ int nid_of_current = numa_node_id();
+- int nid = nid_of_current;
++ int nid_start, nid;
+
+- if (node_isset(nid_of_current, sgx_numa_mask)) {
+- page = __sgx_alloc_epc_page_from_node(nid_of_current);
+- if (page)
+- return page;
+- }
+-
+- /* Fall back to the non-local NUMA nodes: */
+- while (true) {
+- nid = next_node_in(nid, sgx_numa_mask);
+- if (nid == nid_of_current)
+- break;
++ /*
++ * Try local node first. If it doesn't have an EPC section,
++ * fall back to the non-local NUMA nodes.
++ */
++ if (node_isset(nid_of_current, sgx_numa_mask))
++ nid_start = nid_of_current;
++ else
++ nid_start = next_node_in(nid_of_current, sgx_numa_mask);
+
++ nid = nid_start;
++ do {
+ page = __sgx_alloc_epc_page_from_node(nid);
+ if (page)
+ return page;
+- }
++
++ nid = next_node_in(nid, sgx_numa_mask);
++ } while (nid != nid_start);
+
+ return ERR_PTR(-ENOMEM);
+ }
+--
+2.43.0
+
--- /dev/null
+From 42e67170cdf91439034af299778b592a8f6dee83 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Aug 2024 16:47:25 +0200
+Subject: xen: add capability to remap non-RAM pages to different PFNs
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit d05208cf7f05420ad10cc7f9550f91d485523659 ]
+
+When running as a Xen PV dom0 it can happen that the kernel is being
+loaded to a guest physical address conflicting with the host memory
+map.
+
+In order to be able to resolve this conflict, add the capability to
+remap non-RAM areas to different guest PFNs. A function to use this
+remapping information for other purposes than doing the remap will be
+added when needed.
+
+As the number of conflicts should be rather low (currently only
+machines with max. 1 conflict are known), save the remap data in a
+small statically allocated array.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Stable-dep-of: be35d91c8880 ("xen: tolerate ACPI NVS memory overlapping with Xen allocated memory")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/xen/p2m.c | 63 ++++++++++++++++++++++++++++++++++++++++++
+ arch/x86/xen/xen-ops.h | 3 ++
+ 2 files changed, 66 insertions(+)
+
+diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
+index 9b3a9fa4a0ade..d458f2f960ac8 100644
+--- a/arch/x86/xen/p2m.c
++++ b/arch/x86/xen/p2m.c
+@@ -80,6 +80,7 @@
+ #include <asm/xen/hypervisor.h>
+ #include <xen/balloon.h>
+ #include <xen/grant_table.h>
++#include <xen/hvc-console.h>
+
+ #include "multicalls.h"
+ #include "xen-ops.h"
+@@ -799,6 +800,68 @@ int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
+ return ret;
+ }
+
++/* Remapped non-RAM areas */
++#define NR_NONRAM_REMAP 4
++static struct nonram_remap {
++ phys_addr_t maddr;
++ phys_addr_t paddr;
++ size_t size;
++} xen_nonram_remap[NR_NONRAM_REMAP] __ro_after_init;
++static unsigned int nr_nonram_remap __ro_after_init;
++
++/*
++ * Do the real remapping of non-RAM regions as specified in the
++ * xen_nonram_remap[] array.
++ * In case of an error just crash the system.
++ */
++void __init xen_do_remap_nonram(void)
++{
++ unsigned int i;
++ unsigned int remapped = 0;
++ const struct nonram_remap *remap = xen_nonram_remap;
++ unsigned long pfn, mfn, end_pfn;
++
++ for (i = 0; i < nr_nonram_remap; i++) {
++ end_pfn = PFN_UP(remap->paddr + remap->size);
++ pfn = PFN_DOWN(remap->paddr);
++ mfn = PFN_DOWN(remap->maddr);
++ while (pfn < end_pfn) {
++ if (!set_phys_to_machine(pfn, mfn))
++ panic("Failed to set p2m mapping for pfn=%lx mfn=%lx\n",
++ pfn, mfn);
++
++ pfn++;
++ mfn++;
++ remapped++;
++ }
++
++ remap++;
++ }
++
++ pr_info("Remapped %u non-RAM page(s)\n", remapped);
++}
++
++/*
++ * Add a new non-RAM remap entry.
++ * In case of no free entry found, just crash the system.
++ */
++void __init xen_add_remap_nonram(phys_addr_t maddr, phys_addr_t paddr,
++ unsigned long size)
++{
++ BUG_ON((maddr & ~PAGE_MASK) != (paddr & ~PAGE_MASK));
++
++ if (nr_nonram_remap == NR_NONRAM_REMAP) {
++ xen_raw_console_write("Number of required E820 entry remapping actions exceed maximum value\n");
++ BUG();
++ }
++
++ xen_nonram_remap[nr_nonram_remap].maddr = maddr;
++ xen_nonram_remap[nr_nonram_remap].paddr = paddr;
++ xen_nonram_remap[nr_nonram_remap].size = size;
++
++ nr_nonram_remap++;
++}
++
+ #ifdef CONFIG_XEN_DEBUG_FS
+ #include <linux/debugfs.h>
+ #include "debugfs.h"
+diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
+index 55e6e7efb426e..680e26ad436ee 100644
+--- a/arch/x86/xen/xen-ops.h
++++ b/arch/x86/xen/xen-ops.h
+@@ -43,6 +43,9 @@ void xen_mm_unpin_all(void);
+ #ifdef CONFIG_X86_64
+ void __init xen_relocate_p2m(void);
+ #endif
++void __init xen_do_remap_nonram(void);
++void __init xen_add_remap_nonram(phys_addr_t maddr, phys_addr_t paddr,
++ unsigned long size);
+
+ void __init xen_chk_is_e820_usable(phys_addr_t start, phys_addr_t size,
+ const char *component);
+--
+2.43.0
+
--- /dev/null
+From 1a8c7de6df9358657190daa998aba9d93a88752b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Aug 2024 14:11:06 +0200
+Subject: xen: introduce generic helper checking for memory map conflicts
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit ba88829706e2c5b7238638fc2b0713edf596495e ]
+
+When booting as a Xen PV dom0 the memory layout of the dom0 is
+modified to match that of the host, as this requires less changes in
+the kernel for supporting Xen.
+
+There are some cases, though, which are problematic, as it is the Xen
+hypervisor selecting the kernel's load address plus some other data,
+which might conflict with the host's memory map.
+
+These conflicts are detected at boot time and result in a boot error.
+In order to support handling at least some of these conflicts in
+future, introduce a generic helper function which will later gain the
+ability to adapt the memory layout when possible.
+
+Add the missing check for the xen_start_info area.
+
+Note that possible p2m map and initrd memory conflicts are handled
+already by copying the data to memory areas not conflicting with the
+memory map. The initial stack allocated by Xen doesn't need to be
+checked, as early boot code is switching to the statically allocated
+initial kernel stack. Initial page tables and the kernel itself will
+be handled later.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Stable-dep-of: be35d91c8880 ("xen: tolerate ACPI NVS memory overlapping with Xen allocated memory")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/xen/mmu_pv.c | 5 +----
+ arch/x86/xen/setup.c | 34 ++++++++++++++++++++++++++++------
+ arch/x86/xen/xen-ops.h | 3 ++-
+ 3 files changed, 31 insertions(+), 11 deletions(-)
+
+diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c
+index 3359c23573c50..7058490784c54 100644
+--- a/arch/x86/xen/mmu_pv.c
++++ b/arch/x86/xen/mmu_pv.c
+@@ -1987,10 +1987,7 @@ void __init xen_reserve_special_pages(void)
+
+ void __init xen_pt_check_e820(void)
+ {
+- if (xen_is_e820_reserved(xen_pt_base, xen_pt_size)) {
+- xen_raw_console_write("Xen hypervisor allocated page table memory conflicts with E820 map\n");
+- BUG();
+- }
++ xen_chk_is_e820_usable(xen_pt_base, xen_pt_size, "page table");
+ }
+
+ static unsigned char dummy_mapping[PAGE_SIZE] __page_aligned_bss;
+diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
+index dfb11a7420a3f..7fb9c9e368158 100644
+--- a/arch/x86/xen/setup.c
++++ b/arch/x86/xen/setup.c
+@@ -611,7 +611,7 @@ static void __init xen_ignore_unusable(void)
+ }
+ }
+
+-bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size)
++static bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size)
+ {
+ struct e820_entry *entry;
+ unsigned mapcnt;
+@@ -668,6 +668,23 @@ phys_addr_t __init xen_find_free_area(phys_addr_t size)
+ return 0;
+ }
+
++/*
++ * Check for an area in physical memory to be usable for non-movable purposes.
++ * An area is considered to usable if the used E820 map lists it to be RAM.
++ * In case the area is not usable, crash the system with an error message.
++ */
++void __init xen_chk_is_e820_usable(phys_addr_t start, phys_addr_t size,
++ const char *component)
++{
++ if (!xen_is_e820_reserved(start, size))
++ return;
++
++ xen_raw_console_write("Xen hypervisor allocated ");
++ xen_raw_console_write(component);
++ xen_raw_console_write(" memory conflicts with E820 map\n");
++ BUG();
++}
++
+ /*
+ * Like memcpy, but with physical addresses for dest and src.
+ */
+@@ -856,11 +873,16 @@ char * __init xen_memory_setup(void)
+ * Failing now is better than running into weird problems later due
+ * to relocating (and even reusing) pages with kernel text or data.
+ */
+- if (xen_is_e820_reserved(__pa_symbol(_text),
+- __pa_symbol(_end) - __pa_symbol(_text))) {
+- xen_raw_console_write("Xen hypervisor allocated kernel memory conflicts with E820 map\n");
+- BUG();
+- }
++ xen_chk_is_e820_usable(__pa_symbol(_text),
++ __pa_symbol(_end) - __pa_symbol(_text),
++ "kernel");
++
++ /*
++ * Check for a conflict of the xen_start_info memory with the target
++ * E820 map.
++ */
++ xen_chk_is_e820_usable(__pa(xen_start_info), sizeof(*xen_start_info),
++ "xen_start_info");
+
+ /*
+ * Check for a conflict of the hypervisor supplied page tables with
+diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
+index 71f31032c635f..55e6e7efb426e 100644
+--- a/arch/x86/xen/xen-ops.h
++++ b/arch/x86/xen/xen-ops.h
+@@ -44,7 +44,8 @@ void xen_mm_unpin_all(void);
+ void __init xen_relocate_p2m(void);
+ #endif
+
+-bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size);
++void __init xen_chk_is_e820_usable(phys_addr_t start, phys_addr_t size,
++ const char *component);
+ unsigned long __ref xen_chk_extra_mem(unsigned long pfn);
+ void __init xen_inv_extra_mem(void);
+ void __init xen_remap_memory(void);
+--
+2.43.0
+
--- /dev/null
+From 3def24c7def35fae03ff7a9f1a26b0fc11fe91e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Aug 2024 10:24:41 +0200
+Subject: xen: move max_pfn in xen_memory_setup() out of function scope
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit 43dc2a0f479b9cd30f6674986d7a40517e999d31 ]
+
+Instead of having max_pfn as a local variable of xen_memory_setup(),
+make it a static variable in setup.c instead. This avoids having to
+pass it to subfunctions, which will be needed in more cases in future.
+
+Rename it to ini_nr_pages, as the value denotes the currently usable
+number of memory pages as passed from the hypervisor at boot time.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Stable-dep-of: be35d91c8880 ("xen: tolerate ACPI NVS memory overlapping with Xen allocated memory")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/xen/setup.c | 52 ++++++++++++++++++++++----------------------
+ 1 file changed, 26 insertions(+), 26 deletions(-)
+
+diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
+index 7fb9c9e368158..ffe2b3918cbb2 100644
+--- a/arch/x86/xen/setup.c
++++ b/arch/x86/xen/setup.c
+@@ -45,6 +45,9 @@ unsigned long xen_released_pages;
+ /* E820 map used during setting up memory. */
+ static struct e820_table xen_e820_table __initdata;
+
++/* Number of initially usable memory pages. */
++static unsigned long ini_nr_pages __initdata;
++
+ /*
+ * Buffer used to remap identity mapped pages. We only need the virtual space.
+ * The physical page behind this address is remapped as needed to different
+@@ -252,7 +255,7 @@ static int __init xen_free_mfn(unsigned long mfn)
+ * as a fallback if the remapping fails.
+ */
+ static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn,
+- unsigned long end_pfn, unsigned long nr_pages)
++ unsigned long end_pfn)
+ {
+ unsigned long pfn, end;
+ int ret;
+@@ -260,7 +263,7 @@ static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn,
+ WARN_ON(start_pfn > end_pfn);
+
+ /* Release pages first. */
+- end = min(end_pfn, nr_pages);
++ end = min(end_pfn, ini_nr_pages);
+ for (pfn = start_pfn; pfn < end; pfn++) {
+ unsigned long mfn = pfn_to_mfn(pfn);
+
+@@ -385,15 +388,14 @@ static void __init xen_do_set_identity_and_remap_chunk(
+ * to Xen and not remapped.
+ */
+ static unsigned long __init xen_set_identity_and_remap_chunk(
+- unsigned long start_pfn, unsigned long end_pfn, unsigned long nr_pages,
+- unsigned long remap_pfn)
++ unsigned long start_pfn, unsigned long end_pfn, unsigned long remap_pfn)
+ {
+ unsigned long pfn;
+ unsigned long i = 0;
+ unsigned long n = end_pfn - start_pfn;
+
+ if (remap_pfn == 0)
+- remap_pfn = nr_pages;
++ remap_pfn = ini_nr_pages;
+
+ while (i < n) {
+ unsigned long cur_pfn = start_pfn + i;
+@@ -402,19 +404,19 @@ static unsigned long __init xen_set_identity_and_remap_chunk(
+ unsigned long remap_range_size;
+
+ /* Do not remap pages beyond the current allocation */
+- if (cur_pfn >= nr_pages) {
++ if (cur_pfn >= ini_nr_pages) {
+ /* Identity map remaining pages */
+ set_phys_range_identity(cur_pfn, cur_pfn + size);
+ break;
+ }
+- if (cur_pfn + size > nr_pages)
+- size = nr_pages - cur_pfn;
++ if (cur_pfn + size > ini_nr_pages)
++ size = ini_nr_pages - cur_pfn;
+
+ remap_range_size = xen_find_pfn_range(&remap_pfn);
+ if (!remap_range_size) {
+ pr_warn("Unable to find available pfn range, not remapping identity pages\n");
+ xen_set_identity_and_release_chunk(cur_pfn,
+- cur_pfn + left, nr_pages);
++ cur_pfn + left);
+ break;
+ }
+ /* Adjust size to fit in current e820 RAM region */
+@@ -441,18 +443,18 @@ static unsigned long __init xen_set_identity_and_remap_chunk(
+ }
+
+ static unsigned long __init xen_count_remap_pages(
+- unsigned long start_pfn, unsigned long end_pfn, unsigned long nr_pages,
++ unsigned long start_pfn, unsigned long end_pfn,
+ unsigned long remap_pages)
+ {
+- if (start_pfn >= nr_pages)
++ if (start_pfn >= ini_nr_pages)
+ return remap_pages;
+
+- return remap_pages + min(end_pfn, nr_pages) - start_pfn;
++ return remap_pages + min(end_pfn, ini_nr_pages) - start_pfn;
+ }
+
+-static unsigned long __init xen_foreach_remap_area(unsigned long nr_pages,
++static unsigned long __init xen_foreach_remap_area(
+ unsigned long (*func)(unsigned long start_pfn, unsigned long end_pfn,
+- unsigned long nr_pages, unsigned long last_val))
++ unsigned long last_val))
+ {
+ phys_addr_t start = 0;
+ unsigned long ret_val = 0;
+@@ -480,8 +482,7 @@ static unsigned long __init xen_foreach_remap_area(unsigned long nr_pages,
+ end_pfn = PFN_UP(entry->addr);
+
+ if (start_pfn < end_pfn)
+- ret_val = func(start_pfn, end_pfn, nr_pages,
+- ret_val);
++ ret_val = func(start_pfn, end_pfn, ret_val);
+ start = end;
+ }
+ }
+@@ -744,7 +745,7 @@ static void __init xen_reserve_xen_mfnlist(void)
+ **/
+ char * __init xen_memory_setup(void)
+ {
+- unsigned long max_pfn, pfn_s, n_pfns;
++ unsigned long pfn_s, n_pfns;
+ phys_addr_t mem_end, addr, size, chunk_size;
+ u32 type;
+ int rc;
+@@ -756,9 +757,8 @@ char * __init xen_memory_setup(void)
+ int op;
+
+ xen_parse_512gb();
+- max_pfn = xen_get_pages_limit();
+- max_pfn = min(max_pfn, xen_start_info->nr_pages);
+- mem_end = PFN_PHYS(max_pfn);
++ ini_nr_pages = min(xen_get_pages_limit(), xen_start_info->nr_pages);
++ mem_end = PFN_PHYS(ini_nr_pages);
+
+ memmap.nr_entries = ARRAY_SIZE(xen_e820_table.entries);
+ set_xen_guest_handle(memmap.buffer, xen_e820_table.entries);
+@@ -802,10 +802,10 @@ char * __init xen_memory_setup(void)
+ max_pages = xen_get_max_pages();
+
+ /* How many extra pages do we need due to remapping? */
+- max_pages += xen_foreach_remap_area(max_pfn, xen_count_remap_pages);
++ max_pages += xen_foreach_remap_area(xen_count_remap_pages);
+
+- if (max_pages > max_pfn)
+- extra_pages += max_pages - max_pfn;
++ if (max_pages > ini_nr_pages)
++ extra_pages += max_pages - ini_nr_pages;
+
+ /*
+ * Clamp the amount of extra memory to a EXTRA_MEM_RATIO
+@@ -814,8 +814,8 @@ char * __init xen_memory_setup(void)
+ * Make sure we have no memory above max_pages, as this area
+ * isn't handled by the p2m management.
+ */
+- maxmem_pages = EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM));
+- extra_pages = min3(maxmem_pages, extra_pages, max_pages - max_pfn);
++ maxmem_pages = EXTRA_MEM_RATIO * min(ini_nr_pages, PFN_DOWN(MAXMEM));
++ extra_pages = min3(maxmem_pages, extra_pages, max_pages - ini_nr_pages);
+ i = 0;
+ addr = xen_e820_table.entries[0].addr;
+ size = xen_e820_table.entries[0].size;
+@@ -917,7 +917,7 @@ char * __init xen_memory_setup(void)
+ * Set identity map on non-RAM pages and prepare remapping the
+ * underlying RAM.
+ */
+- xen_foreach_remap_area(max_pfn, xen_set_identity_and_remap_chunk);
++ xen_foreach_remap_area(xen_set_identity_and_remap_chunk);
+
+ pr_info("Released %ld page(s)\n", xen_released_pages);
+
+--
+2.43.0
+
--- /dev/null
+From c96f9696fc2708c749d427749c1d48ad6997cc60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Sep 2024 12:05:02 +0200
+Subject: xen/swiotlb: add alignment check for dma buffers
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit 9f40ec84a7976d95c34e7cc070939deb103652b0 ]
+
+When checking a memory buffer to be consecutive in machine memory,
+the alignment needs to be checked, too. Failing to do so might result
+in DMA memory not being aligned according to its requested size,
+leading to error messages like:
+
+ 4xxx 0000:2b:00.0: enabling device (0140 -> 0142)
+ 4xxx 0000:2b:00.0: Ring address not aligned
+ 4xxx 0000:2b:00.0: Failed to initialise service qat_crypto
+ 4xxx 0000:2b:00.0: Resetting device qat_dev0
+ 4xxx: probe of 0000:2b:00.0 failed with error -14
+
+Fixes: 9435cce87950 ("xen/swiotlb: Add support for 64KB page granularity")
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/xen/swiotlb-xen.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
+index 86bcf329ebfbf..0392841a822fa 100644
+--- a/drivers/xen/swiotlb-xen.c
++++ b/drivers/xen/swiotlb-xen.c
+@@ -79,9 +79,15 @@ static inline int range_straddles_page_boundary(phys_addr_t p, size_t size)
+ {
+ unsigned long next_bfn, xen_pfn = XEN_PFN_DOWN(p);
+ unsigned int i, nr_pages = XEN_PFN_UP(xen_offset_in_page(p) + size);
++ phys_addr_t algn = 1ULL << (get_order(size) + PAGE_SHIFT);
+
+ next_bfn = pfn_to_bfn(xen_pfn);
+
++ /* If buffer is physically aligned, ensure DMA alignment. */
++ if (IS_ALIGNED(p, algn) &&
++ !IS_ALIGNED((phys_addr_t)next_bfn << XEN_PAGE_SHIFT, algn))
++ return 1;
++
+ for (i = 1; i < nr_pages; i++)
+ if (pfn_to_bfn(++xen_pfn) != ++next_bfn)
+ return 1;
+--
+2.43.0
+
--- /dev/null
+From b9991477d70059e93a1f1819586a77aaf509149b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Aug 2024 20:14:22 +0200
+Subject: xen: tolerate ACPI NVS memory overlapping with Xen allocated memory
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit be35d91c8880650404f3bf813573222dfb106935 ]
+
+In order to minimize required special handling for running as Xen PV
+dom0, the memory layout is modified to match that of the host. This
+requires to have only RAM at the locations where Xen allocated memory
+is living. Unfortunately there seem to be some machines, where ACPI
+NVS is located at 64 MB, resulting in a conflict with the loaded
+kernel or the initial page tables built by Xen.
+
+Avoid this conflict by swapping the ACPI NVS area in the memory map
+with unused RAM. This is possible via modification of the dom0 P2M map.
+Accesses to the ACPI NVS area are done either for saving and restoring
+it across suspend operations (this will work the same way as before),
+or by ACPI code when NVS memory is referenced from other ACPI tables.
+The latter case is handled by a Xen specific indirection of
+acpi_os_ioremap().
+
+While the E820 map can (and should) be modified right away, the P2M
+map can be updated only after memory allocation is working, as the P2M
+map might need to be extended.
+
+Fixes: 808fdb71936c ("xen: check for kernel memory conflicting with memory layout")
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/xen/setup.c | 92 +++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 91 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
+index ffe2b3918cbb2..5126b5b79383b 100644
+--- a/arch/x86/xen/setup.c
++++ b/arch/x86/xen/setup.c
+@@ -539,6 +539,8 @@ void __init xen_remap_memory(void)
+ set_pte_mfn(buf, mfn_save, PAGE_KERNEL);
+
+ pr_info("Remapped %ld page(s)\n", remapped);
++
++ xen_do_remap_nonram();
+ }
+
+ static unsigned long __init xen_get_pages_limit(void)
+@@ -669,14 +671,102 @@ phys_addr_t __init xen_find_free_area(phys_addr_t size)
+ return 0;
+ }
+
++/*
++ * Swap a non-RAM E820 map entry with RAM above ini_nr_pages.
++ * Note that the E820 map is modified accordingly, but the P2M map isn't yet.
++ * The adaption of the P2M must be deferred until page allocation is possible.
++ */
++static void __init xen_e820_swap_entry_with_ram(struct e820_entry *swap_entry)
++{
++ struct e820_entry *entry;
++ unsigned int mapcnt;
++ phys_addr_t mem_end = PFN_PHYS(ini_nr_pages);
++ phys_addr_t swap_addr, swap_size, entry_end;
++
++ swap_addr = PAGE_ALIGN_DOWN(swap_entry->addr);
++ swap_size = PAGE_ALIGN(swap_entry->addr - swap_addr + swap_entry->size);
++ entry = xen_e820_table.entries;
++
++ for (mapcnt = 0; mapcnt < xen_e820_table.nr_entries; mapcnt++) {
++ entry_end = entry->addr + entry->size;
++ if (entry->type == E820_TYPE_RAM && entry->size >= swap_size &&
++ entry_end - swap_size >= mem_end) {
++ /* Reduce RAM entry by needed space (whole pages). */
++ entry->size -= swap_size;
++
++ /* Add new entry at the end of E820 map. */
++ entry = xen_e820_table.entries +
++ xen_e820_table.nr_entries;
++ xen_e820_table.nr_entries++;
++
++ /* Fill new entry (keep size and page offset). */
++ entry->type = swap_entry->type;
++ entry->addr = entry_end - swap_size +
++ swap_addr - swap_entry->addr;
++ entry->size = swap_entry->size;
++
++ /* Convert old entry to RAM, align to pages. */
++ swap_entry->type = E820_TYPE_RAM;
++ swap_entry->addr = swap_addr;
++ swap_entry->size = swap_size;
++
++ /* Remember PFN<->MFN relation for P2M update. */
++ xen_add_remap_nonram(swap_addr, entry_end - swap_size,
++ swap_size);
++
++ /* Order E820 table and merge entries. */
++ e820__update_table(&xen_e820_table);
++
++ return;
++ }
++
++ entry++;
++ }
++
++ xen_raw_console_write("No suitable area found for required E820 entry remapping action\n");
++ BUG();
++}
++
++/*
++ * Look for non-RAM memory types in a specific guest physical area and move
++ * those away if possible (ACPI NVS only for now).
++ */
++static void __init xen_e820_resolve_conflicts(phys_addr_t start,
++ phys_addr_t size)
++{
++ struct e820_entry *entry;
++ unsigned int mapcnt;
++ phys_addr_t end;
++
++ if (!size)
++ return;
++
++ end = start + size;
++ entry = xen_e820_table.entries;
++
++ for (mapcnt = 0; mapcnt < xen_e820_table.nr_entries; mapcnt++) {
++ if (entry->addr >= end)
++ return;
++
++ if (entry->addr + entry->size > start &&
++ entry->type == E820_TYPE_NVS)
++ xen_e820_swap_entry_with_ram(entry);
++
++ entry++;
++ }
++}
++
+ /*
+ * Check for an area in physical memory to be usable for non-movable purposes.
+- * An area is considered to usable if the used E820 map lists it to be RAM.
++ * An area is considered to usable if the used E820 map lists it to be RAM or
++ * some other type which can be moved to higher PFNs while keeping the MFNs.
+ * In case the area is not usable, crash the system with an error message.
+ */
+ void __init xen_chk_is_e820_usable(phys_addr_t start, phys_addr_t size,
+ const char *component)
+ {
++ xen_e820_resolve_conflicts(start, size);
++
+ if (!xen_is_e820_reserved(start, size))
+ return;
+
+--
+2.43.0
+
--- /dev/null
+From 63307e0d860a04263a873e988a60a4142ced97f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 3 Aug 2024 08:01:22 +0200
+Subject: xen: use correct end address of kernel for conflict checking
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Juergen Gross <jgross@suse.com>
+
+[ Upstream commit fac1bceeeb04886fc2ee952672e6e6c85ce41dca ]
+
+When running as a Xen PV dom0 the kernel is loaded by the hypervisor
+using a different memory map than that of the host. In order to
+minimize the required changes in the kernel, the kernel adapts its
+memory map to that of the host. In order to do that it is checking
+for conflicts of its load address with the host memory map.
+
+Unfortunately the tested memory range does not include the .brk
+area, which might result in crashes or memory corruption when this
+area does conflict with the memory map of the host.
+
+Fix the test by using the _end label instead of __bss_stop.
+
+Fixes: 808fdb71936c ("xen: check for kernel memory conflicting with memory layout")
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/xen/setup.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
+index 1f80dd3a2dd4a..629c94d1ab24c 100644
+--- a/arch/x86/xen/setup.c
++++ b/arch/x86/xen/setup.c
+@@ -856,7 +856,7 @@ char * __init xen_memory_setup(void)
+ * to relocating (and even reusing) pages with kernel text or data.
+ */
+ if (xen_is_e820_reserved(__pa_symbol(_text),
+- __pa_symbol(__bss_stop) - __pa_symbol(_text))) {
++ __pa_symbol(_end) - __pa_symbol(_text))) {
+ xen_raw_console_write("Xen hypervisor allocated kernel memory conflicts with E820 map\n");
+ BUG();
+ }
+--
+2.43.0
+
--- /dev/null
+From ddd81cc22e475ade8297231b78468185408dd5a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 21 Jul 2024 16:36:24 +0300
+Subject: xz: cleanup CRC32 edits from 2018
+
+From: Lasse Collin <lasse.collin@tukaani.org>
+
+[ Upstream commit 2ee96abef214550d9e92f5143ee3ac1fd1323e67 ]
+
+In 2018, a dependency on <linux/crc32poly.h> was added to avoid
+duplicating the same constant in multiple files. Two months later it was
+found to be a bad idea and the definition of CRC32_POLY_LE macro was moved
+into xz_private.h to avoid including <linux/crc32poly.h>.
+
+xz_private.h is a wrong place for it too. Revert back to the upstream
+version which has the poly in xz_crc32_init() in xz_crc32.c.
+
+Link: https://lkml.kernel.org/r/20240721133633.47721-10-lasse.collin@tukaani.org
+Fixes: faa16bc404d7 ("lib: Use existing define with polynomial")
+Fixes: 242cdad873a7 ("lib/xz: Put CRC32_POLY_LE in xz_private.h")
+Signed-off-by: Lasse Collin <lasse.collin@tukaani.org>
+Reviewed-by: Sam James <sam@gentoo.org>
+Tested-by: Michael Ellerman <mpe@ellerman.id.au> (powerpc)
+Cc: Krzysztof Kozlowski <krzk@kernel.org>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: Joel Stanley <joel@jms.id.au>
+Cc: Albert Ou <aou@eecs.berkeley.edu>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Jonathan Corbet <corbet@lwn.net>
+Cc: Jubin Zhong <zhongjubin@huawei.com>
+Cc: Jules Maselbas <jmaselbas@zdiv.net>
+Cc: Palmer Dabbelt <palmer@dabbelt.com>
+Cc: Paul Walmsley <paul.walmsley@sifive.com>
+Cc: Randy Dunlap <rdunlap@infradead.org>
+Cc: Rui Li <me@lirui.org>
+Cc: Simon Glass <sjg@chromium.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Will Deacon <will@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/xz/xz_crc32.c | 2 +-
+ lib/xz/xz_private.h | 4 ----
+ 2 files changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/lib/xz/xz_crc32.c b/lib/xz/xz_crc32.c
+index 88a2c35e1b597..5627b00fca296 100644
+--- a/lib/xz/xz_crc32.c
++++ b/lib/xz/xz_crc32.c
+@@ -29,7 +29,7 @@ STATIC_RW_DATA uint32_t xz_crc32_table[256];
+
+ XZ_EXTERN void xz_crc32_init(void)
+ {
+- const uint32_t poly = CRC32_POLY_LE;
++ const uint32_t poly = 0xEDB88320;
+
+ uint32_t i;
+ uint32_t j;
+diff --git a/lib/xz/xz_private.h b/lib/xz/xz_private.h
+index 09360ebb510ef..482b90f363fe3 100644
+--- a/lib/xz/xz_private.h
++++ b/lib/xz/xz_private.h
+@@ -102,10 +102,6 @@
+ # endif
+ #endif
+
+-#ifndef CRC32_POLY_LE
+-#define CRC32_POLY_LE 0xedb88320
+-#endif
+-
+ /*
+ * Allocate memory for LZMA2 decoder. xz_dec_lzma2_reset() must be used
+ * before calling xz_dec_lzma2_run().
+--
+2.43.0
+