--- /dev/null
+From 2f22e2811f1efdbf9914f99db01fa4e6125d199c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Mar 2024 22:46:50 +0100
+Subject: ahci: asm1064: asm1166: don't limit reported ports
+
+From: Conrad Kostecki <conikost@gentoo.org>
+
+[ Upstream commit 6cd8adc3e18960f6e59d797285ed34ef473cc896 ]
+
+Previously, patches have been added to limit the reported count of SATA
+ports for asm1064 and asm1166 SATA controllers, as those controllers do
+report more ports than physically having.
+
+While it is allowed to report more ports than physically having in CAP.NP,
+it is not allowed to report more ports than physically having in the PI
+(Ports Implemented) register, which is what these HBAs do.
+(This is a AHCI spec violation.)
+
+Unfortunately, it seems that the PMP implementation in these ASMedia HBAs
+is also violating the AHCI and SATA-IO PMP specification.
+
+What these HBAs do is that they do not report that they support PMP
+(CAP.SPM (Supports Port Multiplier) is not set).
+
+Instead, they have decided to add extra "virtual" ports in the PI register
+that is used if a port multiplier is connected to any of the physical
+ports of the HBA.
+
+Enumerating the devices behind the PMP as specified in the AHCI and
+SATA-IO specifications, by using PMP READ and PMP WRITE commands to the
+physical ports of the HBA is not possible, you have to use the "virtual"
+ports.
+
+This is of course bad, because this gives us no way to detect the device
+and vendor ID of the PMP actually connected to the HBA, which means that
+we can not apply the proper PMP quirks for the PMP that is connected to
+the HBA.
+
+Limiting the port map will thus stop these controllers from working with
+SATA Port Multipliers.
+
+This patch reverts both patches for asm1064 and asm1166, so old behavior
+is restored and SATA PMP will work again, but it will also reintroduce the
+(minutes long) extra boot time for the ASMedia controllers that do not
+have a PMP connected (either on the PCIe card itself, or an external PMP).
+
+However, a longer boot time for some, is the lesser evil compared to some
+other users not being able to detect their drives at all.
+
+Fixes: 0077a504e1a4 ("ahci: asm1166: correct count of reported ports")
+Fixes: 9815e3961754 ("ahci: asm1064: correct count of reported ports")
+Cc: stable@vger.kernel.org
+Reported-by: Matt <cryptearth@googlemail.com>
+Signed-off-by: Conrad Kostecki <conikost@gentoo.org>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+[cassel: rewrote commit message]
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/ahci.c | 13 -------------
+ 1 file changed, 13 deletions(-)
+
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index d446830ba4b85..2d2a070c1efcb 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -626,19 +626,6 @@ MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets");
+ static void ahci_pci_save_initial_config(struct pci_dev *pdev,
+ struct ahci_host_priv *hpriv)
+ {
+- if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA) {
+- switch (pdev->device) {
+- case 0x1166:
+- dev_info(&pdev->dev, "ASM1166 has only six ports\n");
+- hpriv->saved_port_map = 0x3f;
+- break;
+- case 0x1064:
+- dev_info(&pdev->dev, "ASM1064 has only four ports\n");
+- hpriv->saved_port_map = 0xf;
+- break;
+- }
+- }
+-
+ if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) {
+ dev_info(&pdev->dev, "JMB361 has only one port\n");
+ hpriv->force_port_map = 1;
+--
+2.43.0
+
--- /dev/null
+From 462c0ee155de082d0f7ef090b73f76f62d6d5626 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Feb 2024 17:57:57 +0100
+Subject: ahci: asm1064: correct count of reported ports
+
+From: Andrey Jr. Melnikov <temnota.am@gmail.com>
+
+[ Upstream commit 9815e39617541ef52d0dfac4be274ad378c6dc09 ]
+
+The ASM1064 SATA host controller always reports wrongly,
+that it has 24 ports. But in reality, it only has four ports.
+
+before:
+ahci 0000:04:00.0: SSS flag set, parallel bus scan disabled
+ahci 0000:04:00.0: AHCI 0001.0301 32 slots 24 ports 6 Gbps 0xffff0f impl SATA mode
+ahci 0000:04:00.0: flags: 64bit ncq sntf stag pm led only pio sxs deso sadm sds apst
+
+after:
+ahci 0000:04:00.0: ASM1064 has only four ports
+ahci 0000:04:00.0: forcing port_map 0xffff0f -> 0xf
+ahci 0000:04:00.0: SSS flag set, parallel bus scan disabled
+ahci 0000:04:00.0: AHCI 0001.0301 32 slots 24 ports 6 Gbps 0xf impl SATA mode
+ahci 0000:04:00.0: flags: 64bit ncq sntf stag pm led only pio sxs deso sadm sds apst
+
+Signed-off-by: "Andrey Jr. Melnikov" <temnota.am@gmail.com>
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Stable-dep-of: 6cd8adc3e189 ("ahci: asm1064: asm1166: don't limit reported ports")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/ahci.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index 84c7519dddb19..d446830ba4b85 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -626,9 +626,17 @@ MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets");
+ static void ahci_pci_save_initial_config(struct pci_dev *pdev,
+ struct ahci_host_priv *hpriv)
+ {
+- if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && pdev->device == 0x1166) {
+- dev_info(&pdev->dev, "ASM1166 has only six ports\n");
+- hpriv->saved_port_map = 0x3f;
++ if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA) {
++ switch (pdev->device) {
++ case 0x1166:
++ dev_info(&pdev->dev, "ASM1166 has only six ports\n");
++ hpriv->saved_port_map = 0x3f;
++ break;
++ case 0x1064:
++ dev_info(&pdev->dev, "ASM1064 has only four ports\n");
++ hpriv->saved_port_map = 0xf;
++ break;
++ }
+ }
+
+ if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) {
+--
+2.43.0
+
--- /dev/null
+From 30851949f89edb6068a6bbf442a956d673d3fe6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Jan 2024 19:39:32 +0100
+Subject: arm: dts: marvell: Fix maxium->maxim typo in brownstone dts
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Duje Mihanović <duje.mihanovic@skole.hr>
+
+[ Upstream commit 831e0cd4f9ee15a4f02ae10b67e7fdc10eb2b4fc ]
+
+Fix an obvious spelling error in the PMIC compatible in the MMP2
+Brownstone DTS file.
+
+Fixes: 58f1193e6210 ("mfd: max8925: Add dts")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Duje Mihanović <duje.mihanovic@skole.hr>
+Reported-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Closes: https://lore.kernel.org/linux-devicetree/1410884282-18041-1-git-send-email-k.kozlowski@samsung.com/
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/20240125-brownstone-typo-fix-v2-1-45bc48a0c81c@skole.hr
+[krzysztof: Just 10 years to take a patch, not bad! Rephrased commit
+ msg]
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/mmp2-brownstone.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts b/arch/arm/boot/dts/mmp2-brownstone.dts
+index 04f1ae1382e7a..bc64348b82185 100644
+--- a/arch/arm/boot/dts/mmp2-brownstone.dts
++++ b/arch/arm/boot/dts/mmp2-brownstone.dts
+@@ -28,7 +28,7 @@ &uart3 {
+ &twsi1 {
+ status = "okay";
+ pmic: max8925@3c {
+- compatible = "maxium,max8925";
++ compatible = "maxim,max8925";
+ reg = <0x3c>;
+ interrupts = <1>;
+ interrupt-parent = <&intcmux4>;
+--
+2.43.0
+
--- /dev/null
+From f09bf20057f84fc9644d62661f1dff8a0f6bc3ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Mar 2020 18:41:01 +0100
+Subject: ARM: dts: mmp2-brownstone: Don't redeclare phandle references
+
+From: Lubomir Rintel <lkundrak@v3.sk>
+
+[ Upstream commit 5a56cf3e8738f5d31d8c024d0c62a4c2bfe76fb2 ]
+
+Extend the nodes by their phandle references instead of recreating the
+tree and declaring references of the same names.
+
+Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20200320174107.29406-5-lkundrak@v3.sk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 831e0cd4f9ee ("arm: dts: marvell: Fix maxium->maxim typo in brownstone dts")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/mmp2-brownstone.dts | 332 +++++++++++++-------------
+ 1 file changed, 165 insertions(+), 167 deletions(-)
+
+diff --git a/arch/arm/boot/dts/mmp2-brownstone.dts b/arch/arm/boot/dts/mmp2-brownstone.dts
+index aaedc4c742ea5..04f1ae1382e7a 100644
+--- a/arch/arm/boot/dts/mmp2-brownstone.dts
++++ b/arch/arm/boot/dts/mmp2-brownstone.dts
+@@ -19,176 +19,174 @@ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x08000000>;
+ };
++};
++
++&uart3 {
++ status = "okay";
++};
+
+- soc {
+- apb@d4000000 {
+- uart3: uart@d4018000 {
+- status = "okay";
+- };
+- twsi1: i2c@d4011000 {
+- status = "okay";
+- pmic: max8925@3c {
+- compatible = "maxium,max8925";
+- reg = <0x3c>;
+- interrupts = <1>;
+- interrupt-parent = <&intcmux4>;
+- interrupt-controller;
+- #interrupt-cells = <1>;
+- maxim,tsc-irq = <0>;
++&twsi1 {
++ status = "okay";
++ pmic: max8925@3c {
++ compatible = "maxium,max8925";
++ reg = <0x3c>;
++ interrupts = <1>;
++ interrupt-parent = <&intcmux4>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ maxim,tsc-irq = <0>;
+
+- regulators {
+- SDV1 {
+- regulator-min-microvolt = <637500>;
+- regulator-max-microvolt = <1425000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- SDV2 {
+- regulator-min-microvolt = <650000>;
+- regulator-max-microvolt = <2225000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- SDV3 {
+- regulator-min-microvolt = <750000>;
+- regulator-max-microvolt = <3900000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO1 {
+- regulator-min-microvolt = <750000>;
+- regulator-max-microvolt = <3900000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO2 {
+- regulator-min-microvolt = <650000>;
+- regulator-max-microvolt = <2250000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO3 {
+- regulator-min-microvolt = <650000>;
+- regulator-max-microvolt = <2250000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO4 {
+- regulator-min-microvolt = <750000>;
+- regulator-max-microvolt = <3900000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO5 {
+- regulator-min-microvolt = <750000>;
+- regulator-max-microvolt = <3900000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO6 {
+- regulator-min-microvolt = <750000>;
+- regulator-max-microvolt = <3900000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO7 {
+- regulator-min-microvolt = <750000>;
+- regulator-max-microvolt = <3900000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO8 {
+- regulator-min-microvolt = <750000>;
+- regulator-max-microvolt = <3900000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO9 {
+- regulator-min-microvolt = <750000>;
+- regulator-max-microvolt = <3900000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO10 {
+- regulator-min-microvolt = <750000>;
+- regulator-max-microvolt = <3900000>;
+- };
+- LDO11 {
+- regulator-min-microvolt = <750000>;
+- regulator-max-microvolt = <3900000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO12 {
+- regulator-min-microvolt = <750000>;
+- regulator-max-microvolt = <3900000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO13 {
+- regulator-min-microvolt = <750000>;
+- regulator-max-microvolt = <3900000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO14 {
+- regulator-min-microvolt = <750000>;
+- regulator-max-microvolt = <3900000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO15 {
+- regulator-min-microvolt = <750000>;
+- regulator-max-microvolt = <3900000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO16 {
+- regulator-min-microvolt = <750000>;
+- regulator-max-microvolt = <3900000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO17 {
+- regulator-min-microvolt = <650000>;
+- regulator-max-microvolt = <2250000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO18 {
+- regulator-min-microvolt = <650000>;
+- regulator-max-microvolt = <2250000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO19 {
+- regulator-min-microvolt = <750000>;
+- regulator-max-microvolt = <3900000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- LDO20 {
+- regulator-min-microvolt = <750000>;
+- regulator-max-microvolt = <3900000>;
+- regulator-boot-on;
+- regulator-always-on;
+- };
+- };
+- backlight {
+- maxim,max8925-dual-string = <0>;
+- };
+- charger {
+- batt-detect = <0>;
+- topoff-threshold = <1>;
+- fast-charge = <7>;
+- no-temp-support = <0>;
+- no-insert-detect = <0>;
+- };
+- };
+- };
+- rtc: rtc@d4010000 {
+- status = "okay";
++ regulators {
++ SDV1 {
++ regulator-min-microvolt = <637500>;
++ regulator-max-microvolt = <1425000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ SDV2 {
++ regulator-min-microvolt = <650000>;
++ regulator-max-microvolt = <2225000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ SDV3 {
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <3900000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO1 {
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <3900000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO2 {
++ regulator-min-microvolt = <650000>;
++ regulator-max-microvolt = <2250000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO3 {
++ regulator-min-microvolt = <650000>;
++ regulator-max-microvolt = <2250000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO4 {
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <3900000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO5 {
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <3900000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO6 {
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <3900000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO7 {
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <3900000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO8 {
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <3900000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO9 {
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <3900000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO10 {
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <3900000>;
+ };
++ LDO11 {
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <3900000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO12 {
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <3900000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO13 {
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <3900000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO14 {
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <3900000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO15 {
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <3900000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO16 {
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <3900000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO17 {
++ regulator-min-microvolt = <650000>;
++ regulator-max-microvolt = <2250000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO18 {
++ regulator-min-microvolt = <650000>;
++ regulator-max-microvolt = <2250000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO19 {
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <3900000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ LDO20 {
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <3900000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++ };
++ backlight {
++ maxim,max8925-dual-string = <0>;
++ };
++ charger {
++ batt-detect = <0>;
++ topoff-threshold = <1>;
++ fast-charge = <7>;
++ no-temp-support = <0>;
++ no-insert-detect = <0>;
+ };
+ };
+ };
++
++&rtc {
++ status = "okay";
++};
+--
+2.43.0
+
--- /dev/null
+From ee3aecc3453220b3120356ed2e39242e02613b00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 10:37:04 +0000
+Subject: btrfs: fix off-by-one chunk length calculation at
+ contains_pending_extent()
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit ae6bd7f9b46a29af52ebfac25d395757e2031d0d ]
+
+At contains_pending_extent() the value of the end offset of a chunk we
+found in the device's allocation state io tree is inclusive, so when
+we calculate the length we pass to the in_range() macro, we must sum
+1 to the expression "physical_end - physical_offset".
+
+In practice the wrong calculation should be harmless as chunks sizes
+are never 1 byte and we should never have 1 byte ranges of unallocated
+space. Nevertheless fix the wrong calculation.
+
+Reported-by: Alex Lyakas <alex.lyakas@zadara.com>
+Link: https://lore.kernel.org/linux-btrfs/CAOcd+r30e-f4R-5x-S7sV22RJPe7+pgwherA6xqN2_qe7o4XTg@mail.gmail.com/
+Fixes: 1c11b63eff2a ("btrfs: replace pending/pinned chunks lists with io tree")
+CC: stable@vger.kernel.org # 6.1+
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/volumes.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index e11c8da9a5605..5539e672d70a3 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -1638,7 +1638,7 @@ static bool contains_pending_extent(struct btrfs_device *device, u64 *start,
+
+ if (in_range(physical_start, *start, len) ||
+ in_range(*start, physical_start,
+- physical_end - physical_start)) {
++ physical_end + 1 - physical_start)) {
+ *start = physical_end + 1;
+ return true;
+ }
+--
+2.43.0
+
--- /dev/null
+From ac3c54a9b71cd909da60a9091a6fc50bdca0b091 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 19:07:48 +0100
+Subject: clk: qcom: gcc-ipq8074: fix terminating of frequency table arrays
+
+From: Gabor Juhos <j4g8y7@gmail.com>
+
+[ Upstream commit 1040ef5ed95d6fd2628bad387d78a61633e09429 ]
+
+The frequency table arrays are supposed to be terminated with an
+empty element. Add such entry to the end of the arrays where it
+is missing in order to avoid possible out-of-bound access when
+the table is traversed by functions like qcom_find_freq() or
+qcom_find_freq_floor().
+
+Only compile tested.
+
+Fixes: 9607f6224b39 ("clk: qcom: ipq8074: add PCIE, USB and SDCC clocks")
+Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
+Reviewed-by: Stephen Boyd <sboyd@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240229-freq-table-terminator-v1-3-074334f0905c@gmail.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-ipq8074.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
+index 052e168d2a2ac..b10ecfde21c87 100644
+--- a/drivers/clk/qcom/gcc-ipq8074.c
++++ b/drivers/clk/qcom/gcc-ipq8074.c
+@@ -972,6 +972,7 @@ static struct clk_rcg2 pcie0_axi_clk_src = {
+
+ static const struct freq_tbl ftbl_pcie_aux_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
++ { }
+ };
+
+ static struct clk_rcg2 pcie0_aux_clk_src = {
+@@ -1077,6 +1078,7 @@ static const struct freq_tbl ftbl_sdcc_ice_core_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(160000000, P_GPLL0, 5, 0, 0),
+ F(308570000, P_GPLL6, 3.5, 0, 0),
++ { }
+ };
+
+ static struct clk_rcg2 sdcc1_ice_core_clk_src = {
+--
+2.43.0
+
--- /dev/null
+From 92cb14ccc6871835151b79ea1f6f731d456d83f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Jan 2024 11:58:14 +0530
+Subject: clk: qcom: gcc-sdm845: Add soft dependency on rpmhpd
+
+From: Amit Pundir <amit.pundir@linaro.org>
+
+[ Upstream commit 1d9054e3a4fd36e2949e616f7360bdb81bcc1921 ]
+
+With the addition of RPMh power domain to the GCC node in
+device tree, we noticed a significant delay in getting the
+UFS driver probed on AOSP which futher led to mount failures
+because Android do not support rootwait. So adding a soft
+dependency on RPMh power domain which informs modprobe to
+load rpmhpd module before gcc-sdm845.
+
+Cc: stable@vger.kernel.org # v5.4+
+Fixes: 4b6ea15c0a11 ("arm64: dts: qcom: sdm845: Add missing RPMh power domain to GCC")
+Suggested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20240123062814.2555649-1-amit.pundir@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/gcc-sdm845.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
+index 56d22dd225c9d..a8810a628e710 100644
+--- a/drivers/clk/qcom/gcc-sdm845.c
++++ b/drivers/clk/qcom/gcc-sdm845.c
+@@ -3646,3 +3646,4 @@ module_exit(gcc_sdm845_exit);
+ MODULE_DESCRIPTION("QTI GCC SDM845 Driver");
+ MODULE_LICENSE("GPL v2");
+ MODULE_ALIAS("platform:gcc-sdm845");
++MODULE_SOFTDEP("pre: rpmhpd");
+--
+2.43.0
+
--- /dev/null
+From 37767219c909a2eccb4a66475eea0990dbb345cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 19:07:51 +0100
+Subject: clk: qcom: mmcc-apq8084: fix terminating of frequency table arrays
+
+From: Gabor Juhos <j4g8y7@gmail.com>
+
+[ Upstream commit a903cfd38d8dee7e754fb89fd1bebed99e28003d ]
+
+The frequency table arrays are supposed to be terminated with an
+empty element. Add such entry to the end of the arrays where it
+is missing in order to avoid possible out-of-bound access when
+the table is traversed by functions like qcom_find_freq() or
+qcom_find_freq_floor().
+
+Only compile tested.
+
+Fixes: 2b46cd23a5a2 ("clk: qcom: Add APQ8084 Multimedia Clock Controller (MMCC) support")
+Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
+Reviewed-by: Stephen Boyd <sboyd@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240229-freq-table-terminator-v1-6-074334f0905c@gmail.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/mmcc-apq8084.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/qcom/mmcc-apq8084.c b/drivers/clk/qcom/mmcc-apq8084.c
+index fbfcf00067394..c2fd0e8f4bc09 100644
+--- a/drivers/clk/qcom/mmcc-apq8084.c
++++ b/drivers/clk/qcom/mmcc-apq8084.c
+@@ -333,6 +333,7 @@ static struct freq_tbl ftbl_mmss_axi_clk[] = {
+ F(333430000, P_MMPLL1, 3.5, 0, 0),
+ F(400000000, P_MMPLL0, 2, 0, 0),
+ F(466800000, P_MMPLL1, 2.5, 0, 0),
++ { }
+ };
+
+ static struct clk_rcg2 mmss_axi_clk_src = {
+@@ -357,6 +358,7 @@ static struct freq_tbl ftbl_ocmemnoc_clk[] = {
+ F(150000000, P_GPLL0, 4, 0, 0),
+ F(228570000, P_MMPLL0, 3.5, 0, 0),
+ F(320000000, P_MMPLL0, 2.5, 0, 0),
++ { }
+ };
+
+ static struct clk_rcg2 ocmemnoc_clk_src = {
+--
+2.43.0
+
--- /dev/null
+From 900e38be6bb1759b2fbddbc286715ce86009ac11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 19:07:52 +0100
+Subject: clk: qcom: mmcc-msm8974: fix terminating of frequency table arrays
+
+From: Gabor Juhos <j4g8y7@gmail.com>
+
+[ Upstream commit e2c02a85bf53ae86d79b5fccf0a75ac0b78e0c96 ]
+
+The frequency table arrays are supposed to be terminated with an
+empty element. Add such entry to the end of the arrays where it
+is missing in order to avoid possible out-of-bound access when
+the table is traversed by functions like qcom_find_freq() or
+qcom_find_freq_floor().
+
+Only compile tested.
+
+Fixes: d8b212014e69 ("clk: qcom: Add support for MSM8974's multimedia clock controller (MMCC)")
+Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
+Reviewed-by: Stephen Boyd <sboyd@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240229-freq-table-terminator-v1-7-074334f0905c@gmail.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/qcom/mmcc-msm8974.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c
+index bcb0a397ef918..8ce1826aea140 100644
+--- a/drivers/clk/qcom/mmcc-msm8974.c
++++ b/drivers/clk/qcom/mmcc-msm8974.c
+@@ -283,6 +283,7 @@ static struct freq_tbl ftbl_mmss_axi_clk[] = {
+ F(291750000, P_MMPLL1, 4, 0, 0),
+ F(400000000, P_MMPLL0, 2, 0, 0),
+ F(466800000, P_MMPLL1, 2.5, 0, 0),
++ { }
+ };
+
+ static struct clk_rcg2 mmss_axi_clk_src = {
+@@ -307,6 +308,7 @@ static struct freq_tbl ftbl_ocmemnoc_clk[] = {
+ F(150000000, P_GPLL0, 4, 0, 0),
+ F(291750000, P_MMPLL1, 4, 0, 0),
+ F(400000000, P_MMPLL0, 2, 0, 0),
++ { }
+ };
+
+ static struct clk_rcg2 ocmemnoc_clk_src = {
+--
+2.43.0
+
--- /dev/null
+From 5aa4f15b9804c4684b5e11bfddf360780561b35c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Oct 2023 13:27:19 +0100
+Subject: crypto: qat - fix double free during reset
+
+From: Svyatoslav Pankratov <svyatoslav.pankratov@intel.com>
+
+[ Upstream commit 01aed663e6c421aeafc9c330bda630976b50a764 ]
+
+There is no need to free the reset_data structure if the recovery is
+unsuccessful and the reset is synchronous. The function
+adf_dev_aer_schedule_reset() handles the cleanup properly. Only
+asynchronous resets require such structure to be freed inside the reset
+worker.
+
+Fixes: d8cba25d2c68 ("crypto: qat - Intel(R) QAT driver framework")
+Signed-off-by: Svyatoslav Pankratov <svyatoslav.pankratov@intel.com>
+Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: 7d42e097607c ("crypto: qat - resolve race condition during AER recovery")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/qat/qat_common/adf_aer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/qat/qat_common/adf_aer.c b/drivers/crypto/qat/qat_common/adf_aer.c
+index f5e960d23a7a7..20f983b830065 100644
+--- a/drivers/crypto/qat/qat_common/adf_aer.c
++++ b/drivers/crypto/qat/qat_common/adf_aer.c
+@@ -139,7 +139,8 @@ static void adf_device_reset_worker(struct work_struct *work)
+ if (adf_dev_init(accel_dev) || adf_dev_start(accel_dev)) {
+ /* The device hanged and we can't restart it so stop here */
+ dev_err(&GET_DEV(accel_dev), "Restart device failed\n");
+- kfree(reset_data);
++ if (reset_data->mode == ADF_DEV_RESET_ASYNC)
++ kfree(reset_data);
+ WARN(1, "QAT: device restart failed. Device is unusable\n");
+ return;
+ }
+--
+2.43.0
+
--- /dev/null
+From 5451aa18ecfed58331298d88f6a6944d090a9fa4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Feb 2024 13:43:42 +0100
+Subject: crypto: qat - resolve race condition during AER recovery
+
+From: Damian Muszynski <damian.muszynski@intel.com>
+
+[ Upstream commit 7d42e097607c4d246d99225bf2b195b6167a210c ]
+
+During the PCI AER system's error recovery process, the kernel driver
+may encounter a race condition with freeing the reset_data structure's
+memory. If the device restart will take more than 10 seconds the function
+scheduling that restart will exit due to a timeout, and the reset_data
+structure will be freed. However, this data structure is used for
+completion notification after the restart is completed, which leads
+to a UAF bug.
+
+This results in a KFENCE bug notice.
+
+ BUG: KFENCE: use-after-free read in adf_device_reset_worker+0x38/0xa0 [intel_qat]
+ Use-after-free read at 0x00000000bc56fddf (in kfence-#142):
+ adf_device_reset_worker+0x38/0xa0 [intel_qat]
+ process_one_work+0x173/0x340
+
+To resolve this race condition, the memory associated to the container
+of the work_struct is freed on the worker if the timeout expired,
+otherwise on the function that schedules the worker.
+The timeout detection can be done by checking if the caller is
+still waiting for completion or not by using completion_done() function.
+
+Fixes: d8cba25d2c68 ("crypto: qat - Intel(R) QAT driver framework")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Damian Muszynski <damian.muszynski@intel.com>
+Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/qat/qat_common/adf_aer.c | 22 ++++++++++++++++------
+ 1 file changed, 16 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/crypto/qat/qat_common/adf_aer.c b/drivers/crypto/qat/qat_common/adf_aer.c
+index 20f983b830065..a2989f0188cad 100644
+--- a/drivers/crypto/qat/qat_common/adf_aer.c
++++ b/drivers/crypto/qat/qat_common/adf_aer.c
+@@ -139,7 +139,8 @@ static void adf_device_reset_worker(struct work_struct *work)
+ if (adf_dev_init(accel_dev) || adf_dev_start(accel_dev)) {
+ /* The device hanged and we can't restart it so stop here */
+ dev_err(&GET_DEV(accel_dev), "Restart device failed\n");
+- if (reset_data->mode == ADF_DEV_RESET_ASYNC)
++ if (reset_data->mode == ADF_DEV_RESET_ASYNC ||
++ completion_done(&reset_data->compl))
+ kfree(reset_data);
+ WARN(1, "QAT: device restart failed. Device is unusable\n");
+ return;
+@@ -147,11 +148,19 @@ static void adf_device_reset_worker(struct work_struct *work)
+ adf_dev_restarted_notify(accel_dev);
+ clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
+
+- /* The dev is back alive. Notify the caller if in sync mode */
+- if (reset_data->mode == ADF_DEV_RESET_SYNC)
+- complete(&reset_data->compl);
+- else
++ /*
++ * The dev is back alive. Notify the caller if in sync mode
++ *
++ * If device restart will take a more time than expected,
++ * the schedule_reset() function can timeout and exit. This can be
++ * detected by calling the completion_done() function. In this case
++ * the reset_data structure needs to be freed here.
++ */
++ if (reset_data->mode == ADF_DEV_RESET_ASYNC ||
++ completion_done(&reset_data->compl))
+ kfree(reset_data);
++ else
++ complete(&reset_data->compl);
+ }
+
+ static int adf_dev_aer_schedule_reset(struct adf_accel_dev *accel_dev,
+@@ -184,8 +193,9 @@ static int adf_dev_aer_schedule_reset(struct adf_accel_dev *accel_dev,
+ dev_err(&GET_DEV(accel_dev),
+ "Reset device timeout expired\n");
+ ret = -EFAULT;
++ } else {
++ kfree(reset_data);
+ }
+- kfree(reset_data);
+ return ret;
+ }
+ return 0;
+--
+2.43.0
+
--- /dev/null
+From e326ab70723f47af48a50805b544d29f691bd0f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 15:23:06 +0800
+Subject: dm-raid: fix lockdep waring in "pers->hot_add_disk"
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+[ Upstream commit 95009ae904b1e9dca8db6f649f2d7c18a6e42c75 ]
+
+The lockdep assert is added by commit a448af25becf ("md/raid10: remove
+rcu protection to access rdev from conf") in print_conf(). And I didn't
+notice that dm-raid is calling "pers->hot_add_disk" without holding
+'reconfig_mutex'.
+
+"pers->hot_add_disk" read and write many fields that is protected by
+'reconfig_mutex', and raid_resume() already grab the lock in other
+contex. Hence fix this problem by protecting "pers->host_add_disk"
+with the lock.
+
+Fixes: 9092c02d9435 ("DM RAID: Add ability to restore transiently failed devices on resume")
+Fixes: a448af25becf ("md/raid10: remove rcu protection to access rdev from conf")
+Cc: stable@vger.kernel.org # v6.7+
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Xiao Ni <xni@redhat.com>
+Acked-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Song Liu <song@kernel.org>
+Link: https://lore.kernel.org/r/20240305072306.2562024-10-yukuai1@huaweicloud.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-raid.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
+index 1ccd765fad938..25eecb92f5f38 100644
+--- a/drivers/md/dm-raid.c
++++ b/drivers/md/dm-raid.c
+@@ -4027,7 +4027,9 @@ static void raid_resume(struct dm_target *ti)
+ * Take this opportunity to check whether any failed
+ * devices are reachable again.
+ */
++ mddev_lock_nointr(mddev);
+ attempt_restore_of_faulty_devices(rs);
++ mddev_unlock(mddev);
+ }
+
+ if (test_and_clear_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) {
+--
+2.43.0
+
--- /dev/null
+From 101f87a83c2afb4bffda0905079ba6250f134db7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Mar 2024 18:43:11 +0100
+Subject: dm snapshot: fix lockup in dm_exception_table_exit
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+[ Upstream commit 6e7132ed3c07bd8a6ce3db4bb307ef2852b322dc ]
+
+There was reported lockup when we exit a snapshot with many exceptions.
+Fix this by adding "cond_resched" to the loop that frees the exceptions.
+
+Reported-by: John Pittman <jpittman@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-snap.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
+index e902aae685af9..d8902d2b6aa66 100644
+--- a/drivers/md/dm-snap.c
++++ b/drivers/md/dm-snap.c
+@@ -685,8 +685,10 @@ static void dm_exception_table_exit(struct dm_exception_table *et,
+ for (i = 0; i < size; i++) {
+ slot = et->table + i;
+
+- hlist_bl_for_each_entry_safe(ex, pos, n, slot, hash_list)
++ hlist_bl_for_each_entry_safe(ex, pos, n, slot, hash_list) {
+ kmem_cache_free(mem, ex);
++ cond_resched();
++ }
+ }
+
+ vfree(et->table);
+--
+2.43.0
+
--- /dev/null
+From ad1cebc6eee7b89a489a73caa05cb44c1536823d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Mar 2024 18:03:41 +0200
+Subject: drm/exynos: do not return negative values from .get_modes()
+
+From: Jani Nikula <jani.nikula@intel.com>
+
+[ Upstream commit 13d5b040363c7ec0ac29c2de9cf661a24a8aa531 ]
+
+The .get_modes() hooks aren't supposed to return negative error
+codes. Return 0 for no modes, whatever the reason.
+
+Cc: Inki Dae <inki.dae@samsung.com>
+Cc: Seung-Woo Kim <sw0312.kim@samsung.com>
+Cc: Kyungmin Park <kyungmin.park@samsung.com>
+Cc: stable@vger.kernel.org
+Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/d8665f620d9c252aa7d5a4811ff6b16e773903a2.1709913674.git.jani.nikula@intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/exynos/exynos_drm_vidi.c | 4 ++--
+ drivers/gpu/drm/exynos/exynos_hdmi.c | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+index d882a22dfd6e6..46fc472be3068 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+@@ -308,14 +308,14 @@ static int vidi_get_modes(struct drm_connector *connector)
+ */
+ if (!ctx->raw_edid) {
+ DRM_DEV_DEBUG_KMS(ctx->dev, "raw_edid is null.\n");
+- return -EFAULT;
++ return 0;
+ }
+
+ edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH;
+ edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL);
+ if (!edid) {
+ DRM_DEV_DEBUG_KMS(ctx->dev, "failed to allocate edid\n");
+- return -ENOMEM;
++ return 0;
+ }
+
+ drm_connector_update_edid_property(connector, edid);
+diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
+index 93b2af4936d0e..0e2e1dfcd9ce5 100644
+--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
++++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
+@@ -876,11 +876,11 @@ static int hdmi_get_modes(struct drm_connector *connector)
+ int ret;
+
+ if (!hdata->ddc_adpt)
+- return -ENODEV;
++ return 0;
+
+ edid = drm_get_edid(connector, hdata->ddc_adpt);
+ if (!edid)
+- return -ENODEV;
++ return 0;
+
+ hdata->dvi_mode = !drm_detect_hdmi_monitor(edid);
+ DRM_DEV_DEBUG_KMS(hdata->dev, "%s : width[%d] x height[%d]\n",
+--
+2.43.0
+
--- /dev/null
+From a75274a4104014cccb27d98fbc0d99770ed5b5aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Mar 2024 18:03:43 +0200
+Subject: drm/imx/ipuv3: do not return negative values from .get_modes()
+
+From: Jani Nikula <jani.nikula@intel.com>
+
+[ Upstream commit c2da9ada64962fcd2e6395ed9987b9874ea032d3 ]
+
+The .get_modes() hooks aren't supposed to return negative error
+codes. Return 0 for no modes, whatever the reason.
+
+Cc: Philipp Zabel <p.zabel@pengutronix.de>
+Cc: stable@vger.kernel.org
+Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
+Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/311f6eec96d47949b16a670529f4d89fcd97aefa.1709913674.git.jani.nikula@intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/imx/parallel-display.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
+index e24272428744c..2165ad545a382 100644
+--- a/drivers/gpu/drm/imx/parallel-display.c
++++ b/drivers/gpu/drm/imx/parallel-display.c
+@@ -63,14 +63,14 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector)
+ int ret;
+
+ if (!mode)
+- return -EINVAL;
++ return 0;
+
+ ret = of_get_drm_display_mode(np, &imxpd->mode,
+ &imxpd->bus_flags,
+ OF_USE_NATIVE_MODE);
+ if (ret) {
+ drm_mode_destroy(connector->dev, mode);
+- return ret;
++ return 0;
+ }
+
+ drm_mode_copy(mode, &imxpd->mode);
+--
+2.43.0
+
--- /dev/null
+From f6612d3221f416bc30017423994dfbfd900e4bf9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Mar 2024 18:03:44 +0200
+Subject: drm/vc4: hdmi: do not return negative values from .get_modes()
+
+From: Jani Nikula <jani.nikula@intel.com>
+
+[ Upstream commit abf493988e380f25242c1023275c68bd3579c9ce ]
+
+The .get_modes() hooks aren't supposed to return negative error
+codes. Return 0 for no modes, whatever the reason.
+
+Cc: Maxime Ripard <mripard@kernel.org>
+Cc: stable@vger.kernel.org
+Acked-by: Maxime Ripard <mripard@kernel.org>
+Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/dcda6d4003e2c6192987916b35c7304732800e08.1709913674.git.jani.nikula@intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 54435b72b7611..ba71200169866 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -236,7 +236,7 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
+ edid = drm_get_edid(connector, vc4->hdmi->ddc);
+ cec_s_phys_addr_from_edid(vc4->hdmi->cec_adap, edid);
+ if (!edid)
+- return -ENODEV;
++ return 0;
+
+ vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid);
+
+--
+2.43.0
+
--- /dev/null
+From e6705a0254e5189dee1166d8707962d98e427c40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Feb 2024 22:18:45 +0800
+Subject: ext4: correct best extent lstart adjustment logic
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit 4fbf8bc733d14bceb16dda46a3f5e19c6a9621c5 ]
+
+When yangerkun review commit 93cdf49f6eca ("ext4: Fix best extent lstart
+adjustment logic in ext4_mb_new_inode_pa()"), it was found that the best
+extent did not completely cover the original request after adjusting the
+best extent lstart in ext4_mb_new_inode_pa() as follows:
+
+ original request: 2/10(8)
+ normalized request: 0/64(64)
+ best extent: 0/9(9)
+
+When we check if best ex can be kept at start of goal, ac_o_ex.fe_logical
+is 2 less than the adjusted best extent logical end 9, so we think the
+adjustment is done. But obviously 0/9(9) doesn't cover 2/10(8), so we
+should determine here if the original request logical end is less than or
+equal to the adjusted best extent logical end.
+
+In addition, add a comment stating when adjusted best_ex will not cover
+the original request, and remove the duplicate assertion because adjusting
+lstart makes no change to b_ex.fe_len.
+
+Link: https://lore.kernel.org/r/3630fa7f-b432-7afd-5f79-781bc3b2c5ea@huawei.com
+Fixes: 93cdf49f6eca ("ext4: Fix best extent lstart adjustment logic in ext4_mb_new_inode_pa()")
+Cc: <stable@kernel.org>
+Signed-off-by: yangerkun <yangerkun@huawei.com>
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Link: https://lore.kernel.org/r/20240201141845.1879253-1-libaokun1@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/mballoc.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index e823731110e3e..b2e7b1907d410 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -3692,10 +3692,16 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
+ .fe_len = ac->ac_g_ex.fe_len,
+ };
+ loff_t orig_goal_end = extent_logical_end(sbi, &ex);
++ loff_t o_ex_end = extent_logical_end(sbi, &ac->ac_o_ex);
+
+- /* we can't allocate as much as normalizer wants.
+- * so, found space must get proper lstart
+- * to cover original request */
++ /*
++ * We can't allocate as much as normalizer wants, so we try
++ * to get proper lstart to cover the original request, except
++ * when the goal doesn't cover the original request as below:
++ *
++ * orig_ex:2045/2055(10), isize:8417280 -> normalized:0/2048
++ * best_ex:0/200(200) -> adjusted: 1848/2048(200)
++ */
+ BUG_ON(ac->ac_g_ex.fe_logical > ac->ac_o_ex.fe_logical);
+ BUG_ON(ac->ac_g_ex.fe_len < ac->ac_o_ex.fe_len);
+
+@@ -3707,7 +3713,7 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
+ * 1. Check if best ex can be kept at end of goal and still
+ * cover original start
+ * 2. Else, check if best ex can be kept at start of goal and
+- * still cover original start
++ * still cover original end
+ * 3. Else, keep the best ex at start of original request.
+ */
+ ex.fe_len = ac->ac_b_ex.fe_len;
+@@ -3717,7 +3723,7 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
+ goto adjust_bex;
+
+ ex.fe_logical = ac->ac_g_ex.fe_logical;
+- if (ac->ac_o_ex.fe_logical < extent_logical_end(sbi, &ex))
++ if (o_ex_end <= extent_logical_end(sbi, &ex))
+ goto adjust_bex;
+
+ ex.fe_logical = ac->ac_o_ex.fe_logical;
+@@ -3725,7 +3731,6 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
+ ac->ac_b_ex.fe_logical = ex.fe_logical;
+
+ BUG_ON(ac->ac_o_ex.fe_logical < ac->ac_b_ex.fe_logical);
+- BUG_ON(ac->ac_o_ex.fe_len > ac->ac_b_ex.fe_len);
+ BUG_ON(extent_logical_end(sbi, &ex) > orig_goal_end);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 04972897ee2f8e26842c6c00ac34332524176aff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Feb 2024 15:50:09 +0000
+Subject: ext4: fix corruption during on-line resize
+
+From: Maximilian Heyne <mheyne@amazon.de>
+
+[ Upstream commit a6b3bfe176e8a5b05ec4447404e412c2a3fc92cc ]
+
+We observed a corruption during on-line resize of a file system that is
+larger than 16 TiB with 4k block size. With having more then 2^32 blocks
+resize_inode is turned off by default by mke2fs. The issue can be
+reproduced on a smaller file system for convenience by explicitly
+turning off resize_inode. An on-line resize across an 8 GiB boundary (the
+size of a meta block group in this setup) then leads to a corruption:
+
+ dev=/dev/<some_dev> # should be >= 16 GiB
+ mkdir -p /corruption
+ /sbin/mke2fs -t ext4 -b 4096 -O ^resize_inode $dev $((2 * 2**21 - 2**15))
+ mount -t ext4 $dev /corruption
+
+ dd if=/dev/zero bs=4096 of=/corruption/test count=$((2*2**21 - 4*2**15))
+ sha1sum /corruption/test
+ # 79d2658b39dcfd77274e435b0934028adafaab11 /corruption/test
+
+ /sbin/resize2fs $dev $((2*2**21))
+ # drop page cache to force reload the block from disk
+ echo 1 > /proc/sys/vm/drop_caches
+
+ sha1sum /corruption/test
+ # 3c2abc63cbf1a94c9e6977e0fbd72cd832c4d5c3 /corruption/test
+
+2^21 = 2^15*2^6 equals 8 GiB whereof 2^15 is the number of blocks per
+block group and 2^6 are the number of block groups that make a meta
+block group.
+
+The last checksum might be different depending on how the file is laid
+out across the physical blocks. The actual corruption occurs at physical
+block 63*2^15 = 2064384 which would be the location of the backup of the
+meta block group's block descriptor. During the on-line resize the file
+system will be converted to meta_bg starting at s_first_meta_bg which is
+2 in the example - meaning all block groups after 16 GiB. However, in
+ext4_flex_group_add we might add block groups that are not part of the
+first meta block group yet. In the reproducer we achieved this by
+substracting the size of a whole block group from the point where the
+meta block group would start. This must be considered when updating the
+backup block group descriptors to follow the non-meta_bg layout. The fix
+is to add a test whether the group to add is already part of the meta
+block group or not.
+
+Fixes: 01f795f9e0d67 ("ext4: add online resizing support for meta_bg and 64-bit file systems")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Maximilian Heyne <mheyne@amazon.de>
+Tested-by: Srivathsa Dara <srivathsa.d.dara@oracle.com>
+Reviewed-by: Srivathsa Dara <srivathsa.d.dara@oracle.com>
+Link: https://lore.kernel.org/r/20240215155009.94493-1-mheyne@amazon.de
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/resize.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
+index 409b4ad28e718..d4431ca0c10e3 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1567,7 +1567,8 @@ static int ext4_flex_group_add(struct super_block *sb,
+ int gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
+ int gdb_num_end = ((group + flex_gd->count - 1) /
+ EXT4_DESC_PER_BLOCK(sb));
+- int meta_bg = ext4_has_feature_meta_bg(sb);
++ int meta_bg = ext4_has_feature_meta_bg(sb) &&
++ gdb_num >= le32_to_cpu(es->s_first_meta_bg);
+ sector_t padding_blocks = meta_bg ? 0 : sbi->s_sbh->b_blocknr -
+ ext4_group_first_block_no(sb, 0);
+ sector_t old_gdb = 0;
+--
+2.43.0
+
--- /dev/null
+From b31b138105b9b15d2a4a8cee6f56fad8bd90540a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Feb 2024 13:26:26 +0100
+Subject: fat: fix uninitialized field in nostale filehandles
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit fde2497d2bc3a063d8af88b258dbadc86bd7b57c ]
+
+When fat_encode_fh_nostale() encodes file handle without a parent it
+stores only first 10 bytes of the file handle. However the length of the
+file handle must be a multiple of 4 so the file handle is actually 12
+bytes long and the last two bytes remain uninitialized. This is not
+great at we potentially leak uninitialized information with the handle
+to userspace. Properly initialize the full handle length.
+
+Link: https://lkml.kernel.org/r/20240205122626.13701-1-jack@suse.cz
+Reported-by: syzbot+3ce5dea5b1539ff36769@syzkaller.appspotmail.com
+Fixes: ea3983ace6b7 ("fat: restructure export_operations")
+Signed-off-by: Jan Kara <jack@suse.cz>
+Acked-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+Cc: Amir Goldstein <amir73il@gmail.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fat/nfs.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/fs/fat/nfs.c b/fs/fat/nfs.c
+index af191371c3529..bab63eeaf9cbc 100644
+--- a/fs/fat/nfs.c
++++ b/fs/fat/nfs.c
+@@ -130,6 +130,12 @@ fat_encode_fh_nostale(struct inode *inode, __u32 *fh, int *lenp,
+ fid->parent_i_gen = parent->i_generation;
+ type = FILEID_FAT_WITH_PARENT;
+ *lenp = FAT_FID_SIZE_WITH_PARENT;
++ } else {
++ /*
++ * We need to initialize this field because the fh is actually
++ * 12 bytes long
++ */
++ fid->parent_i_pos_hi = 0;
+ }
+
+ return type;
+--
+2.43.0
+
--- /dev/null
+From 00f77340d3c1ac58aee9c6a5b97773b77e4bc0fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jul 2019 09:23:39 +0100
+Subject: firmware: meson_sm: Rework driver as a proper platform driver
+
+From: Carlo Caione <ccaione@baylibre.com>
+
+[ Upstream commit 8cde3c2153e8f57be884c0e73f18bc4de150e870 ]
+
+The secure monitor driver is currently a frankenstein driver which is
+registered as a platform driver but its functionality goes through a
+global struct accessed by the consumer drivers using exported helper
+functions.
+
+Try to tidy up the driver moving the firmware struct into the driver
+data and make the consumer drivers referencing the secure-monitor using
+a new property in the DT.
+
+Currently only the nvmem driver is using this API so we can fix it in
+the same commit.
+
+Reviewed-by: Jerome Brunet <jbrunet@baylibre.com>
+Signed-off-by: Carlo Caione <ccaione@baylibre.com>
+Signed-off-by: Kevin Hilman <khilman@baylibre.com>
+Stable-dep-of: cbd38332c140 ("nvmem: meson-efuse: fix function pointer type mismatch")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/meson/meson_sm.c | 94 +++++++++++++++++--------
+ drivers/nvmem/meson-efuse.c | 24 ++++++-
+ include/linux/firmware/meson/meson_sm.h | 15 ++--
+ 3 files changed, 94 insertions(+), 39 deletions(-)
+
+diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c
+index 8d908a8e0d20f..7608704512054 100644
+--- a/drivers/firmware/meson/meson_sm.c
++++ b/drivers/firmware/meson/meson_sm.c
+@@ -54,8 +54,6 @@ struct meson_sm_firmware {
+ void __iomem *sm_shmem_out_base;
+ };
+
+-static struct meson_sm_firmware fw;
+-
+ static u32 meson_sm_get_cmd(const struct meson_sm_chip *chip,
+ unsigned int cmd_index)
+ {
+@@ -90,6 +88,7 @@ static void __iomem *meson_sm_map_shmem(u32 cmd_shmem, unsigned int size)
+ /**
+ * meson_sm_call - generic SMC32 call to the secure-monitor
+ *
++ * @fw: Pointer to secure-monitor firmware
+ * @cmd_index: Index of the SMC32 function ID
+ * @ret: Returned value
+ * @arg0: SMC32 Argument 0
+@@ -100,15 +99,15 @@ static void __iomem *meson_sm_map_shmem(u32 cmd_shmem, unsigned int size)
+ *
+ * Return: 0 on success, a negative value on error
+ */
+-int meson_sm_call(unsigned int cmd_index, u32 *ret, u32 arg0,
+- u32 arg1, u32 arg2, u32 arg3, u32 arg4)
++int meson_sm_call(struct meson_sm_firmware *fw, unsigned int cmd_index,
++ u32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
+ {
+ u32 cmd, lret;
+
+- if (!fw.chip)
++ if (!fw->chip)
+ return -ENOENT;
+
+- cmd = meson_sm_get_cmd(fw.chip, cmd_index);
++ cmd = meson_sm_get_cmd(fw->chip, cmd_index);
+ if (!cmd)
+ return -EINVAL;
+
+@@ -124,6 +123,7 @@ EXPORT_SYMBOL(meson_sm_call);
+ /**
+ * meson_sm_call_read - retrieve data from secure-monitor
+ *
++ * @fw: Pointer to secure-monitor firmware
+ * @buffer: Buffer to store the retrieved data
+ * @bsize: Size of the buffer
+ * @cmd_index: Index of the SMC32 function ID
+@@ -137,22 +137,23 @@ EXPORT_SYMBOL(meson_sm_call);
+ * When 0 is returned there is no guarantee about the amount of
+ * data read and bsize bytes are copied in buffer.
+ */
+-int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index,
+- u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
++int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer,
++ unsigned int bsize, unsigned int cmd_index, u32 arg0,
++ u32 arg1, u32 arg2, u32 arg3, u32 arg4)
+ {
+ u32 size;
+ int ret;
+
+- if (!fw.chip)
++ if (!fw->chip)
+ return -ENOENT;
+
+- if (!fw.chip->cmd_shmem_out_base)
++ if (!fw->chip->cmd_shmem_out_base)
+ return -EINVAL;
+
+- if (bsize > fw.chip->shmem_size)
++ if (bsize > fw->chip->shmem_size)
+ return -EINVAL;
+
+- if (meson_sm_call(cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0)
++ if (meson_sm_call(fw, cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0)
+ return -EINVAL;
+
+ if (size > bsize)
+@@ -164,7 +165,7 @@ int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index,
+ size = bsize;
+
+ if (buffer)
+- memcpy(buffer, fw.sm_shmem_out_base, size);
++ memcpy(buffer, fw->sm_shmem_out_base, size);
+
+ return ret;
+ }
+@@ -173,6 +174,7 @@ EXPORT_SYMBOL(meson_sm_call_read);
+ /**
+ * meson_sm_call_write - send data to secure-monitor
+ *
++ * @fw: Pointer to secure-monitor firmware
+ * @buffer: Buffer containing data to send
+ * @size: Size of the data to send
+ * @cmd_index: Index of the SMC32 function ID
+@@ -184,23 +186,24 @@ EXPORT_SYMBOL(meson_sm_call_read);
+ *
+ * Return: size of sent data on success, a negative value on error
+ */
+-int meson_sm_call_write(void *buffer, unsigned int size, unsigned int cmd_index,
+- u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
++int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
++ unsigned int size, unsigned int cmd_index, u32 arg0,
++ u32 arg1, u32 arg2, u32 arg3, u32 arg4)
+ {
+ u32 written;
+
+- if (!fw.chip)
++ if (!fw->chip)
+ return -ENOENT;
+
+- if (size > fw.chip->shmem_size)
++ if (size > fw->chip->shmem_size)
+ return -EINVAL;
+
+- if (!fw.chip->cmd_shmem_in_base)
++ if (!fw->chip->cmd_shmem_in_base)
+ return -EINVAL;
+
+- memcpy(fw.sm_shmem_in_base, buffer, size);
++ memcpy(fw->sm_shmem_in_base, buffer, size);
+
+- if (meson_sm_call(cmd_index, &written, arg0, arg1, arg2, arg3, arg4) < 0)
++ if (meson_sm_call(fw, cmd_index, &written, arg0, arg1, arg2, arg3, arg4) < 0)
+ return -EINVAL;
+
+ if (!written)
+@@ -210,6 +213,24 @@ int meson_sm_call_write(void *buffer, unsigned int size, unsigned int cmd_index,
+ }
+ EXPORT_SYMBOL(meson_sm_call_write);
+
++/**
++ * meson_sm_get - get pointer to meson_sm_firmware structure.
++ *
++ * @sm_node: Pointer to the secure-monitor Device Tree node.
++ *
++ * Return: NULL is the secure-monitor device is not ready.
++ */
++struct meson_sm_firmware *meson_sm_get(struct device_node *sm_node)
++{
++ struct platform_device *pdev = of_find_device_by_node(sm_node);
++
++ if (!pdev)
++ return NULL;
++
++ return platform_get_drvdata(pdev);
++}
++EXPORT_SYMBOL_GPL(meson_sm_get);
++
+ #define SM_CHIP_ID_LENGTH 119
+ #define SM_CHIP_ID_OFFSET 4
+ #define SM_CHIP_ID_SIZE 12
+@@ -217,14 +238,18 @@ EXPORT_SYMBOL(meson_sm_call_write);
+ static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+ {
++ struct platform_device *pdev = to_platform_device(dev);
++ struct meson_sm_firmware *fw;
+ uint8_t *id_buf;
+ int ret;
+
++ fw = platform_get_drvdata(pdev);
++
+ id_buf = kmalloc(SM_CHIP_ID_LENGTH, GFP_KERNEL);
+ if (!id_buf)
+ return -ENOMEM;
+
+- ret = meson_sm_call_read(id_buf, SM_CHIP_ID_LENGTH, SM_GET_CHIP_ID,
++ ret = meson_sm_call_read(fw, id_buf, SM_CHIP_ID_LENGTH, SM_GET_CHIP_ID,
+ 0, 0, 0, 0, 0);
+ if (ret < 0) {
+ kfree(id_buf);
+@@ -268,25 +293,34 @@ static const struct of_device_id meson_sm_ids[] = {
+
+ static int __init meson_sm_probe(struct platform_device *pdev)
+ {
++ struct device *dev = &pdev->dev;
+ const struct meson_sm_chip *chip;
++ struct meson_sm_firmware *fw;
++
++ fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL);
++ if (!fw)
++ return -ENOMEM;
+
+- chip = of_match_device(meson_sm_ids, &pdev->dev)->data;
++ chip = of_match_device(meson_sm_ids, dev)->data;
+
+ if (chip->cmd_shmem_in_base) {
+- fw.sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base,
+- chip->shmem_size);
+- if (WARN_ON(!fw.sm_shmem_in_base))
++ fw->sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base,
++ chip->shmem_size);
++ if (WARN_ON(!fw->sm_shmem_in_base))
+ goto out;
+ }
+
+ if (chip->cmd_shmem_out_base) {
+- fw.sm_shmem_out_base = meson_sm_map_shmem(chip->cmd_shmem_out_base,
+- chip->shmem_size);
+- if (WARN_ON(!fw.sm_shmem_out_base))
++ fw->sm_shmem_out_base = meson_sm_map_shmem(chip->cmd_shmem_out_base,
++ chip->shmem_size);
++ if (WARN_ON(!fw->sm_shmem_out_base))
+ goto out_in_base;
+ }
+
+- fw.chip = chip;
++ fw->chip = chip;
++
++ platform_set_drvdata(pdev, fw);
++
+ pr_info("secure-monitor enabled\n");
+
+ if (sysfs_create_group(&pdev->dev.kobj, &meson_sm_sysfs_attr_group))
+@@ -295,7 +329,7 @@ static int __init meson_sm_probe(struct platform_device *pdev)
+ return 0;
+
+ out_in_base:
+- iounmap(fw.sm_shmem_in_base);
++ iounmap(fw->sm_shmem_in_base);
+ out:
+ return -EINVAL;
+ }
+diff --git a/drivers/nvmem/meson-efuse.c b/drivers/nvmem/meson-efuse.c
+index 39bd76306033f..d6b533497ce1a 100644
+--- a/drivers/nvmem/meson-efuse.c
++++ b/drivers/nvmem/meson-efuse.c
+@@ -17,14 +17,18 @@
+ static int meson_efuse_read(void *context, unsigned int offset,
+ void *val, size_t bytes)
+ {
+- return meson_sm_call_read((u8 *)val, bytes, SM_EFUSE_READ, offset,
++ struct meson_sm_firmware *fw = context;
++
++ return meson_sm_call_read(fw, (u8 *)val, bytes, SM_EFUSE_READ, offset,
+ bytes, 0, 0, 0);
+ }
+
+ static int meson_efuse_write(void *context, unsigned int offset,
+ void *val, size_t bytes)
+ {
+- return meson_sm_call_write((u8 *)val, bytes, SM_EFUSE_WRITE, offset,
++ struct meson_sm_firmware *fw = context;
++
++ return meson_sm_call_write(fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset,
+ bytes, 0, 0, 0);
+ }
+
+@@ -37,12 +41,25 @@ MODULE_DEVICE_TABLE(of, meson_efuse_match);
+ static int meson_efuse_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
++ struct meson_sm_firmware *fw;
++ struct device_node *sm_np;
+ struct nvmem_device *nvmem;
+ struct nvmem_config *econfig;
+ struct clk *clk;
+ unsigned int size;
+ int ret;
+
++ sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0);
++ if (!sm_np) {
++ dev_err(&pdev->dev, "no secure-monitor node\n");
++ return -ENODEV;
++ }
++
++ fw = meson_sm_get(sm_np);
++ of_node_put(sm_np);
++ if (!fw)
++ return -EPROBE_DEFER;
++
+ clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+@@ -65,7 +82,7 @@ static int meson_efuse_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+- if (meson_sm_call(SM_EFUSE_USER_MAX, &size, 0, 0, 0, 0, 0) < 0) {
++ if (meson_sm_call(fw, SM_EFUSE_USER_MAX, &size, 0, 0, 0, 0, 0) < 0) {
+ dev_err(dev, "failed to get max user");
+ return -EINVAL;
+ }
+@@ -81,6 +98,7 @@ static int meson_efuse_probe(struct platform_device *pdev)
+ econfig->reg_read = meson_efuse_read;
+ econfig->reg_write = meson_efuse_write;
+ econfig->size = size;
++ econfig->priv = fw;
+
+ nvmem = devm_nvmem_register(&pdev->dev, econfig);
+
+diff --git a/include/linux/firmware/meson/meson_sm.h b/include/linux/firmware/meson/meson_sm.h
+index 7613bf7c94428..6669e2a1d5fdc 100644
+--- a/include/linux/firmware/meson/meson_sm.h
++++ b/include/linux/firmware/meson/meson_sm.h
+@@ -16,11 +16,14 @@ enum {
+
+ struct meson_sm_firmware;
+
+-int meson_sm_call(unsigned int cmd_index, u32 *ret, u32 arg0, u32 arg1,
+- u32 arg2, u32 arg3, u32 arg4);
+-int meson_sm_call_write(void *buffer, unsigned int b_size, unsigned int cmd_index,
+- u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4);
+-int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index,
+- u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4);
++int meson_sm_call(struct meson_sm_firmware *fw, unsigned int cmd_index,
++ u32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4);
++int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
++ unsigned int b_size, unsigned int cmd_index, u32 arg0,
++ u32 arg1, u32 arg2, u32 arg3, u32 arg4);
++int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer,
++ unsigned int bsize, unsigned int cmd_index, u32 arg0,
++ u32 arg1, u32 arg2, u32 arg3, u32 arg4);
++struct meson_sm_firmware *meson_sm_get(struct device_node *firmware_node);
+
+ #endif /* _MESON_SM_FW_H_ */
+--
+2.43.0
+
--- /dev/null
+From 82dc6b1c14b9413bda118a23192fc0cc56c57e3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Feb 2024 16:50:49 +0100
+Subject: fuse: don't unhash root
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+[ Upstream commit b1fe686a765e6c0d71811d825b5a1585a202b777 ]
+
+The root inode is assumed to be always hashed. Do not unhash the root
+inode even if it is marked BAD.
+
+Fixes: 5d069dbe8aaf ("fuse: fix bad inode")
+Cc: <stable@vger.kernel.org> # v5.11
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fuse/fuse_i.h | 1 -
+ fs/fuse/inode.c | 7 +++++--
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
+index b7bd2e623c3f3..676bc4a191afb 100644
+--- a/fs/fuse/fuse_i.h
++++ b/fs/fuse/fuse_i.h
+@@ -795,7 +795,6 @@ static inline u64 fuse_get_attr_version(struct fuse_conn *fc)
+
+ static inline void fuse_make_bad(struct inode *inode)
+ {
+- remove_inode_hash(inode);
+ set_bit(FUSE_I_BAD, &get_fuse_inode(inode)->state);
+ }
+
+diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
+index f3d712decb57c..287e850fbd644 100644
+--- a/fs/fuse/inode.c
++++ b/fs/fuse/inode.c
+@@ -313,8 +313,11 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid,
+ } else if ((inode->i_mode ^ attr->mode) & S_IFMT) {
+ /* Inode has changed type, any I/O on the old should fail */
+ fuse_make_bad(inode);
+- iput(inode);
+- goto retry;
++ if (inode != d_inode(sb->s_root)) {
++ remove_inode_hash(inode);
++ iput(inode);
++ goto retry;
++ }
+ }
+
+ fi = get_fuse_inode(inode);
+--
+2.43.0
+
--- /dev/null
+From 58e9060ef80221da9887c99a190f06486930f7ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2020 17:59:34 +0200
+Subject: fuse: drop fuse_conn parameter where possible
+
+From: Max Reitz <mreitz@redhat.com>
+
+[ Upstream commit 8f622e9497bbbd5df4675edf782500cd9fe961ba ]
+
+With the last commit, all functions that handle some existing fuse_req
+no longer need to be given the associated fuse_conn, because they can
+get it from the fuse_req object.
+
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Stable-dep-of: b1fe686a765e ("fuse: don't unhash root")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fuse/dev.c | 70 +++++++++++++++++++++++++--------------------
+ fs/fuse/fuse_i.h | 2 +-
+ fs/fuse/virtio_fs.c | 8 ++----
+ 3 files changed, 43 insertions(+), 37 deletions(-)
+
+diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
+index 185cae8a7ce11..96fcb004190e2 100644
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -101,7 +101,7 @@ static void fuse_drop_waiting(struct fuse_conn *fc)
+ }
+ }
+
+-static void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
++static void fuse_put_request(struct fuse_req *req);
+
+ static struct fuse_req *fuse_get_req(struct fuse_conn *fc, bool for_background)
+ {
+@@ -144,7 +144,7 @@ static struct fuse_req *fuse_get_req(struct fuse_conn *fc, bool for_background)
+
+ if (unlikely(req->in.h.uid == ((uid_t)-1) ||
+ req->in.h.gid == ((gid_t)-1))) {
+- fuse_put_request(fc, req);
++ fuse_put_request(req);
+ return ERR_PTR(-EOVERFLOW);
+ }
+ return req;
+@@ -154,8 +154,10 @@ static struct fuse_req *fuse_get_req(struct fuse_conn *fc, bool for_background)
+ return ERR_PTR(err);
+ }
+
+-static void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
++static void fuse_put_request(struct fuse_req *req)
+ {
++ struct fuse_conn *fc = req->fc;
++
+ if (refcount_dec_and_test(&req->count)) {
+ if (test_bit(FR_BACKGROUND, &req->flags)) {
+ /*
+@@ -274,8 +276,9 @@ static void flush_bg_queue(struct fuse_conn *fc)
+ * the 'end' callback is called if given, else the reference to the
+ * request is released
+ */
+-void fuse_request_end(struct fuse_conn *fc, struct fuse_req *req)
++void fuse_request_end(struct fuse_req *req)
+ {
++ struct fuse_conn *fc = req->fc;
+ struct fuse_iqueue *fiq = &fc->iq;
+
+ if (test_and_set_bit(FR_FINISHED, &req->flags))
+@@ -326,12 +329,14 @@ void fuse_request_end(struct fuse_conn *fc, struct fuse_req *req)
+ if (test_bit(FR_ASYNC, &req->flags))
+ req->args->end(fc, req->args, req->out.h.error);
+ put_request:
+- fuse_put_request(fc, req);
++ fuse_put_request(req);
+ }
+ EXPORT_SYMBOL_GPL(fuse_request_end);
+
+-static int queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req)
++static int queue_interrupt(struct fuse_req *req)
+ {
++ struct fuse_iqueue *fiq = &req->fc->iq;
++
+ spin_lock(&fiq->lock);
+ /* Check for we've sent request to interrupt this req */
+ if (unlikely(!test_bit(FR_INTERRUPTED, &req->flags))) {
+@@ -358,8 +363,9 @@ static int queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req)
+ return 0;
+ }
+
+-static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
++static void request_wait_answer(struct fuse_req *req)
+ {
++ struct fuse_conn *fc = req->fc;
+ struct fuse_iqueue *fiq = &fc->iq;
+ int err;
+
+@@ -374,7 +380,7 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
+ /* matches barrier in fuse_dev_do_read() */
+ smp_mb__after_atomic();
+ if (test_bit(FR_SENT, &req->flags))
+- queue_interrupt(fiq, req);
++ queue_interrupt(req);
+ }
+
+ if (!test_bit(FR_FORCE, &req->flags)) {
+@@ -403,9 +409,9 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
+ wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags));
+ }
+
+-static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
++static void __fuse_request_send(struct fuse_req *req)
+ {
+- struct fuse_iqueue *fiq = &fc->iq;
++ struct fuse_iqueue *fiq = &req->fc->iq;
+
+ BUG_ON(test_bit(FR_BACKGROUND, &req->flags));
+ spin_lock(&fiq->lock);
+@@ -419,7 +425,7 @@ static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
+ __fuse_get_request(req);
+ queue_request_and_unlock(fiq, req);
+
+- request_wait_answer(fc, req);
++ request_wait_answer(req);
+ /* Pairs with smp_wmb() in fuse_request_end() */
+ smp_rmb();
+ }
+@@ -458,8 +464,10 @@ static void fuse_adjust_compat(struct fuse_conn *fc, struct fuse_args *args)
+ }
+ }
+
+-static void fuse_force_creds(struct fuse_conn *fc, struct fuse_req *req)
++static void fuse_force_creds(struct fuse_req *req)
+ {
++ struct fuse_conn *fc = req->fc;
++
+ req->in.h.uid = from_kuid_munged(fc->user_ns, current_fsuid());
+ req->in.h.gid = from_kgid_munged(fc->user_ns, current_fsgid());
+ req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
+@@ -484,7 +492,7 @@ ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args)
+ req = fuse_request_alloc(fc, GFP_KERNEL | __GFP_NOFAIL);
+
+ if (!args->nocreds)
+- fuse_force_creds(fc, req);
++ fuse_force_creds(req);
+
+ __set_bit(FR_WAITING, &req->flags);
+ __set_bit(FR_FORCE, &req->flags);
+@@ -501,20 +509,20 @@ ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args)
+
+ if (!args->noreply)
+ __set_bit(FR_ISREPLY, &req->flags);
+- __fuse_request_send(fc, req);
++ __fuse_request_send(req);
+ ret = req->out.h.error;
+ if (!ret && args->out_argvar) {
+ BUG_ON(args->out_numargs == 0);
+ ret = args->out_args[args->out_numargs - 1].size;
+ }
+- fuse_put_request(fc, req);
++ fuse_put_request(req);
+
+ return ret;
+ }
+
+-static bool fuse_request_queue_background(struct fuse_conn *fc,
+- struct fuse_req *req)
++static bool fuse_request_queue_background(struct fuse_req *req)
+ {
++ struct fuse_conn *fc = req->fc;
+ bool queued = false;
+
+ WARN_ON(!test_bit(FR_BACKGROUND, &req->flags));
+@@ -561,8 +569,8 @@ int fuse_simple_background(struct fuse_conn *fc, struct fuse_args *args,
+
+ fuse_args_to_req(req, args);
+
+- if (!fuse_request_queue_background(fc, req)) {
+- fuse_put_request(fc, req);
++ if (!fuse_request_queue_background(req)) {
++ fuse_put_request(req);
+ return -ENOTCONN;
+ }
+
+@@ -592,7 +600,7 @@ static int fuse_simple_notify_reply(struct fuse_conn *fc,
+ } else {
+ err = -ENODEV;
+ spin_unlock(&fiq->lock);
+- fuse_put_request(fc, req);
++ fuse_put_request(req);
+ }
+
+ return err;
+@@ -1277,7 +1285,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
+ /* SETXATTR is special, since it may contain too large data */
+ if (args->opcode == FUSE_SETXATTR)
+ req->out.h.error = -E2BIG;
+- fuse_request_end(fc, req);
++ fuse_request_end(req);
+ goto restart;
+ }
+ spin_lock(&fpq->lock);
+@@ -1320,8 +1328,8 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
+ /* matches barrier in request_wait_answer() */
+ smp_mb__after_atomic();
+ if (test_bit(FR_INTERRUPTED, &req->flags))
+- queue_interrupt(fiq, req);
+- fuse_put_request(fc, req);
++ queue_interrupt(req);
++ fuse_put_request(req);
+
+ return reqsize;
+
+@@ -1329,7 +1337,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
+ if (!test_bit(FR_PRIVATE, &req->flags))
+ list_del_init(&req->list);
+ spin_unlock(&fpq->lock);
+- fuse_request_end(fc, req);
++ fuse_request_end(req);
+ return err;
+
+ err_unlock:
+@@ -1911,9 +1919,9 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
+ else if (oh.error == -ENOSYS)
+ fc->no_interrupt = 1;
+ else if (oh.error == -EAGAIN)
+- err = queue_interrupt(&fc->iq, req);
++ err = queue_interrupt(req);
+
+- fuse_put_request(fc, req);
++ fuse_put_request(req);
+
+ goto copy_finish;
+ }
+@@ -1943,7 +1951,7 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
+ list_del_init(&req->list);
+ spin_unlock(&fpq->lock);
+
+- fuse_request_end(fc, req);
++ fuse_request_end(req);
+ out:
+ return err ? err : nbytes;
+
+@@ -2079,7 +2087,7 @@ static __poll_t fuse_dev_poll(struct file *file, poll_table *wait)
+ }
+
+ /* Abort all requests on the given list (pending or processing) */
+-static void end_requests(struct fuse_conn *fc, struct list_head *head)
++static void end_requests(struct list_head *head)
+ {
+ while (!list_empty(head)) {
+ struct fuse_req *req;
+@@ -2087,7 +2095,7 @@ static void end_requests(struct fuse_conn *fc, struct list_head *head)
+ req->out.h.error = -ECONNABORTED;
+ clear_bit(FR_SENT, &req->flags);
+ list_del_init(&req->list);
+- fuse_request_end(fc, req);
++ fuse_request_end(req);
+ }
+ }
+
+@@ -2182,7 +2190,7 @@ void fuse_abort_conn(struct fuse_conn *fc)
+ wake_up_all(&fc->blocked_waitq);
+ spin_unlock(&fc->lock);
+
+- end_requests(fc, &to_end);
++ end_requests(&to_end);
+ } else {
+ spin_unlock(&fc->lock);
+ }
+@@ -2212,7 +2220,7 @@ int fuse_dev_release(struct inode *inode, struct file *file)
+ list_splice_init(&fpq->processing[i], &to_end);
+ spin_unlock(&fpq->lock);
+
+- end_requests(fc, &to_end);
++ end_requests(&to_end);
+
+ /* Are we the last open device? */
+ if (atomic_dec_and_test(&fc->dev_count)) {
+diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
+index 7138b780c9abd..b7bd2e623c3f3 100644
+--- a/fs/fuse/fuse_i.h
++++ b/fs/fuse/fuse_i.h
+@@ -941,7 +941,7 @@ int fuse_simple_background(struct fuse_conn *fc, struct fuse_args *args,
+ /**
+ * End a finished request
+ */
+-void fuse_request_end(struct fuse_conn *fc, struct fuse_req *req);
++void fuse_request_end(struct fuse_req *req);
+
+ /* Abort all requests */
+ void fuse_abort_conn(struct fuse_conn *fc);
+diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
+index fadf6fb90fe22..8865ab961abfe 100644
+--- a/fs/fuse/virtio_fs.c
++++ b/fs/fuse/virtio_fs.c
+@@ -268,7 +268,6 @@ static void virtio_fs_request_dispatch_work(struct work_struct *work)
+ struct fuse_req *req;
+ struct virtio_fs_vq *fsvq = container_of(work, struct virtio_fs_vq,
+ dispatch_work.work);
+- struct fuse_conn *fc = fsvq->fud->fc;
+ int ret;
+
+ pr_debug("virtio-fs: worker %s called.\n", __func__);
+@@ -283,7 +282,7 @@ static void virtio_fs_request_dispatch_work(struct work_struct *work)
+
+ list_del_init(&req->list);
+ spin_unlock(&fsvq->lock);
+- fuse_request_end(fc, req);
++ fuse_request_end(req);
+ }
+
+ /* Dispatch pending requests */
+@@ -314,7 +313,7 @@ static void virtio_fs_request_dispatch_work(struct work_struct *work)
+ spin_unlock(&fsvq->lock);
+ pr_err("virtio-fs: virtio_fs_enqueue_req() failed %d\n",
+ ret);
+- fuse_request_end(fc, req);
++ fuse_request_end(req);
+ }
+ }
+ }
+@@ -453,7 +452,6 @@ static void virtio_fs_request_complete(struct fuse_req *req,
+ struct virtio_fs_vq *fsvq)
+ {
+ struct fuse_pqueue *fpq = &fsvq->fud->pq;
+- struct fuse_conn *fc = fsvq->fud->fc;
+ struct fuse_args *args;
+ struct fuse_args_pages *ap;
+ unsigned int len, i, thislen;
+@@ -486,7 +484,7 @@ static void virtio_fs_request_complete(struct fuse_req *req,
+ clear_bit(FR_SENT, &req->flags);
+ spin_unlock(&fpq->lock);
+
+- fuse_request_end(fc, req);
++ fuse_request_end(req);
+ spin_lock(&fsvq->lock);
+ dec_in_flight_req(fsvq);
+ spin_unlock(&fsvq->lock);
+--
+2.43.0
+
--- /dev/null
+From 437aa1e2b0ce897e451b5a41c9a5a3db6aa9f7e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2020 17:54:38 +0200
+Subject: fuse: store fuse_conn in fuse_req
+
+From: Max Reitz <mreitz@redhat.com>
+
+[ Upstream commit 24754db2728a87c513cc480c70c09072a7a40ba6 ]
+
+Every fuse_req belongs to a fuse_conn. Right now, we always know which
+fuse_conn that is based on the respective device, but we want to allow
+multiple (sub)mounts per single connection, and then the corresponding
+filesystem is not going to be so trivial to obtain.
+
+Storing a pointer to the associated fuse_conn in every fuse_req will
+allow us to trivially find any request's superblock (and thus
+filesystem) even then.
+
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Stable-dep-of: b1fe686a765e ("fuse: don't unhash root")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/fuse/dev.c | 13 +++++++------
+ fs/fuse/fuse_i.h | 3 +++
+ 2 files changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
+index ac6a8da340139..185cae8a7ce11 100644
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -40,20 +40,21 @@ static struct fuse_dev *fuse_get_dev(struct file *file)
+ return READ_ONCE(file->private_data);
+ }
+
+-static void fuse_request_init(struct fuse_req *req)
++static void fuse_request_init(struct fuse_conn *fc, struct fuse_req *req)
+ {
+ INIT_LIST_HEAD(&req->list);
+ INIT_LIST_HEAD(&req->intr_entry);
+ init_waitqueue_head(&req->waitq);
+ refcount_set(&req->count, 1);
+ __set_bit(FR_PENDING, &req->flags);
++ req->fc = fc;
+ }
+
+-static struct fuse_req *fuse_request_alloc(gfp_t flags)
++static struct fuse_req *fuse_request_alloc(struct fuse_conn *fc, gfp_t flags)
+ {
+ struct fuse_req *req = kmem_cache_zalloc(fuse_req_cachep, flags);
+ if (req)
+- fuse_request_init(req);
++ fuse_request_init(fc, req);
+
+ return req;
+ }
+@@ -125,7 +126,7 @@ static struct fuse_req *fuse_get_req(struct fuse_conn *fc, bool for_background)
+ if (fc->conn_error)
+ goto out;
+
+- req = fuse_request_alloc(GFP_KERNEL);
++ req = fuse_request_alloc(fc, GFP_KERNEL);
+ err = -ENOMEM;
+ if (!req) {
+ if (for_background)
+@@ -480,7 +481,7 @@ ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args)
+
+ if (args->force) {
+ atomic_inc(&fc->num_waiting);
+- req = fuse_request_alloc(GFP_KERNEL | __GFP_NOFAIL);
++ req = fuse_request_alloc(fc, GFP_KERNEL | __GFP_NOFAIL);
+
+ if (!args->nocreds)
+ fuse_force_creds(fc, req);
+@@ -547,7 +548,7 @@ int fuse_simple_background(struct fuse_conn *fc, struct fuse_args *args,
+
+ if (args->force) {
+ WARN_ON(!args->nocreds);
+- req = fuse_request_alloc(gfp_flags);
++ req = fuse_request_alloc(fc, gfp_flags);
+ if (!req)
+ return -ENOMEM;
+ __set_bit(FR_BACKGROUND, &req->flags);
+diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
+index 83c2855bc7406..7138b780c9abd 100644
+--- a/fs/fuse/fuse_i.h
++++ b/fs/fuse/fuse_i.h
+@@ -363,6 +363,9 @@ struct fuse_req {
+ /** virtio-fs's physically contiguous buffer for in and out args */
+ void *argbuf;
+ #endif
++
++ /** fuse_conn this request belongs to */
++ struct fuse_conn *fc;
+ };
+
+ struct fuse_iqueue;
+--
+2.43.0
+
--- /dev/null
+From 08f28a0fc60fac7c2f52a77b10a98b149ff28891 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 12:06:58 +0100
+Subject: hwmon: (amc6821) add of_match table
+
+From: Josua Mayer <josua@solid-run.com>
+
+[ Upstream commit 3f003fda98a7a8d5f399057d92e6ed56b468657c ]
+
+Add of_match table for "ti,amc6821" compatible string.
+This fixes automatic driver loading by userspace when using device-tree,
+and if built as a module like major linux distributions do.
+
+While devices probe just fine with i2c_device_id table, userspace can't
+match the "ti,amc6821" compatible string from dt with the plain
+"amc6821" device id. As a result, the kernel module can not be loaded.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+Link: https://lore.kernel.org/r/20240307-amc6821-of-match-v1-1-5f40464a3110@solid-run.com
+[groeck: Cleaned up patch description]
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/amc6821.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c
+index 013fb056b1d02..a8e94d73eaa04 100644
+--- a/drivers/hwmon/amc6821.c
++++ b/drivers/hwmon/amc6821.c
+@@ -935,10 +935,21 @@ static const struct i2c_device_id amc6821_id[] = {
+
+ MODULE_DEVICE_TABLE(i2c, amc6821_id);
+
++static const struct of_device_id __maybe_unused amc6821_of_match[] = {
++ {
++ .compatible = "ti,amc6821",
++ .data = (void *)amc6821,
++ },
++ { }
++};
++
++MODULE_DEVICE_TABLE(of, amc6821_of_match);
++
+ static struct i2c_driver amc6821_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "amc6821",
++ .of_match_table = of_match_ptr(amc6821_of_match),
+ },
+ .probe = amc6821_probe,
+ .id_table = amc6821_id,
+--
+2.43.0
+
--- /dev/null
+From 5e354914ef3da9fe773c833469be40f0efdd559c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 15:12:47 -0700
+Subject: kbuild: Move -Wenum-{compare-conditional,enum-conversion} into W=1
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+[ Upstream commit 75b5ab134bb5f657ef7979a59106dce0657e8d87 ]
+
+Clang enables -Wenum-enum-conversion and -Wenum-compare-conditional
+under -Wenum-conversion. A recent change in Clang strengthened these
+warnings and they appear frequently in common builds, primarily due to
+several instances in common headers but there are quite a few drivers
+that have individual instances as well.
+
+ include/linux/vmstat.h:508:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
+ 508 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
+ | ~~~~~~~~~~~~~~~~~~~~~ ^
+ 509 | item];
+ | ~~~~
+
+ drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c:955:24: warning: conditional expression between different enumeration types ('enum iwl_mac_beacon_flags' and 'enum iwl_mac_beacon_flags_v1') [-Wenum-compare-conditional]
+ 955 | flags |= is_new_rate ? IWL_MAC_BEACON_CCK
+ | ^ ~~~~~~~~~~~~~~~~~~
+ 956 | : IWL_MAC_BEACON_CCK_V1;
+ | ~~~~~~~~~~~~~~~~~~~~~
+ drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c:1120:21: warning: conditional expression between different enumeration types ('enum iwl_mac_beacon_flags' and 'enum iwl_mac_beacon_flags_v1') [-Wenum-compare-conditional]
+ 1120 | 0) > 10 ?
+ | ^
+ 1121 | IWL_MAC_BEACON_FILS :
+ | ~~~~~~~~~~~~~~~~~~~
+ 1122 | IWL_MAC_BEACON_FILS_V1;
+ | ~~~~~~~~~~~~~~~~~~~~~~
+
+Doing arithmetic between or returning two different types of enums could
+be a bug, so each of the instance of the warning needs to be evaluated.
+Unfortunately, as mentioned above, there are many instances of this
+warning in many different configurations, which can break the build when
+CONFIG_WERROR is enabled.
+
+To avoid introducing new instances of the warnings while cleaning up the
+disruption for the majority of users, disable these warnings for the
+default build while leaving them on for W=1 builds.
+
+Cc: stable@vger.kernel.org
+Closes: https://github.com/ClangBuiltLinux/linux/issues/2002
+Link: https://github.com/llvm/llvm-project/commit/8c2ae42b3e1c6aa7c18f873edcebff7c0b45a37e
+Acked-by: Yonghong Song <yonghong.song@linux.dev>
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/Makefile.extrawarn | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
+index 6a78afc6f13b4..a51193485c50f 100644
+--- a/scripts/Makefile.extrawarn
++++ b/scripts/Makefile.extrawarn
+@@ -51,6 +51,8 @@ KBUILD_CFLAGS += -Wno-format-zero-length
+ KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast)
+ KBUILD_CFLAGS += $(call cc-disable-warning, unaligned-access)
+ KBUILD_CFLAGS += $(call cc-disable-warning, cast-function-type-strict)
++KBUILD_CFLAGS += -Wno-enum-compare-conditional
++KBUILD_CFLAGS += -Wno-enum-enum-conversion
+ endif
+
+ endif
+--
+2.43.0
+
--- /dev/null
+From 31e45bfb63b6a2b735bd32e1d6b0092063375d2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jan 2024 17:15:30 -0800
+Subject: KVM: Always flush async #PF workqueue when vCPU is being destroyed
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit 3d75b8aa5c29058a512db29da7cbee8052724157 ]
+
+Always flush the per-vCPU async #PF workqueue when a vCPU is clearing its
+completion queue, e.g. when a VM and all its vCPUs is being destroyed.
+KVM must ensure that none of its workqueue callbacks is running when the
+last reference to the KVM _module_ is put. Gifting a reference to the
+associated VM prevents the workqueue callback from dereferencing freed
+vCPU/VM memory, but does not prevent the KVM module from being unloaded
+before the callback completes.
+
+Drop the misguided VM refcount gifting, as calling kvm_put_kvm() from
+async_pf_execute() if kvm_put_kvm() flushes the async #PF workqueue will
+result in deadlock. async_pf_execute() can't return until kvm_put_kvm()
+finishes, and kvm_put_kvm() can't return until async_pf_execute() finishes:
+
+ WARNING: CPU: 8 PID: 251 at virt/kvm/kvm_main.c:1435 kvm_put_kvm+0x2d/0x320 [kvm]
+ Modules linked in: vhost_net vhost vhost_iotlb tap kvm_intel kvm irqbypass
+ CPU: 8 PID: 251 Comm: kworker/8:1 Tainted: G W 6.6.0-rc1-e7af8d17224a-x86/gmem-vm #119
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
+ Workqueue: events async_pf_execute [kvm]
+ RIP: 0010:kvm_put_kvm+0x2d/0x320 [kvm]
+ Call Trace:
+ <TASK>
+ async_pf_execute+0x198/0x260 [kvm]
+ process_one_work+0x145/0x2d0
+ worker_thread+0x27e/0x3a0
+ kthread+0xba/0xe0
+ ret_from_fork+0x2d/0x50
+ ret_from_fork_asm+0x11/0x20
+ </TASK>
+ ---[ end trace 0000000000000000 ]---
+ INFO: task kworker/8:1:251 blocked for more than 120 seconds.
+ Tainted: G W 6.6.0-rc1-e7af8d17224a-x86/gmem-vm #119
+ "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+ task:kworker/8:1 state:D stack:0 pid:251 ppid:2 flags:0x00004000
+ Workqueue: events async_pf_execute [kvm]
+ Call Trace:
+ <TASK>
+ __schedule+0x33f/0xa40
+ schedule+0x53/0xc0
+ schedule_timeout+0x12a/0x140
+ __wait_for_common+0x8d/0x1d0
+ __flush_work.isra.0+0x19f/0x2c0
+ kvm_clear_async_pf_completion_queue+0x129/0x190 [kvm]
+ kvm_arch_destroy_vm+0x78/0x1b0 [kvm]
+ kvm_put_kvm+0x1c1/0x320 [kvm]
+ async_pf_execute+0x198/0x260 [kvm]
+ process_one_work+0x145/0x2d0
+ worker_thread+0x27e/0x3a0
+ kthread+0xba/0xe0
+ ret_from_fork+0x2d/0x50
+ ret_from_fork_asm+0x11/0x20
+ </TASK>
+
+If kvm_clear_async_pf_completion_queue() actually flushes the workqueue,
+then there's no need to gift async_pf_execute() a reference because all
+invocations of async_pf_execute() will be forced to complete before the
+vCPU and its VM are destroyed/freed. And that in turn fixes the module
+unloading bug as __fput() won't do module_put() on the last vCPU reference
+until the vCPU has been freed, e.g. if closing the vCPU file also puts the
+last reference to the KVM module.
+
+Note that kvm_check_async_pf_completion() may also take the work item off
+the completion queue and so also needs to flush the work queue, as the
+work will not be seen by kvm_clear_async_pf_completion_queue(). Waiting
+on the workqueue could theoretically delay a vCPU due to waiting for the
+work to complete, but that's a very, very small chance, and likely a very
+small delay. kvm_arch_async_page_present_queued() unconditionally makes a
+new request, i.e. will effectively delay entering the guest, so the
+remaining work is really just:
+
+ trace_kvm_async_pf_completed(addr, cr2_or_gpa);
+
+ __kvm_vcpu_wake_up(vcpu);
+
+ mmput(mm);
+
+and mmput() can't drop the last reference to the page tables if the vCPU is
+still alive, i.e. the vCPU won't get stuck tearing down page tables.
+
+Add a helper to do the flushing, specifically to deal with "wakeup all"
+work items, as they aren't actually work items, i.e. are never placed in a
+workqueue. Trying to flush a bogus workqueue entry rightly makes
+__flush_work() complain (kudos to whoever added that sanity check).
+
+Note, commit 5f6de5cbebee ("KVM: Prevent module exit until all VMs are
+freed") *tried* to fix the module refcounting issue by having VMs grab a
+reference to the module, but that only made the bug slightly harder to hit
+as it gave async_pf_execute() a bit more time to complete before the KVM
+module could be unloaded.
+
+Fixes: af585b921e5d ("KVM: Halt vcpu if page it tries to access is swapped out")
+Cc: stable@vger.kernel.org
+Cc: David Matlack <dmatlack@google.com>
+Reviewed-by: Xu Yilun <yilun.xu@intel.com>
+Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Link: https://lore.kernel.org/r/20240110011533.503302-2-seanjc@google.com
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ virt/kvm/async_pf.c | 31 ++++++++++++++++++++++++++-----
+ 1 file changed, 26 insertions(+), 5 deletions(-)
+
+diff --git a/virt/kvm/async_pf.c b/virt/kvm/async_pf.c
+index d8ef708a2ef67..d0a1113b0e55c 100644
+--- a/virt/kvm/async_pf.c
++++ b/virt/kvm/async_pf.c
+@@ -98,7 +98,27 @@ static void async_pf_execute(struct work_struct *work)
+ swake_up_one(&vcpu->wq);
+
+ mmput(mm);
+- kvm_put_kvm(vcpu->kvm);
++}
++
++static void kvm_flush_and_free_async_pf_work(struct kvm_async_pf *work)
++{
++ /*
++ * The async #PF is "done", but KVM must wait for the work item itself,
++ * i.e. async_pf_execute(), to run to completion. If KVM is a module,
++ * KVM must ensure *no* code owned by the KVM (the module) can be run
++ * after the last call to module_put(). Note, flushing the work item
++ * is always required when the item is taken off the completion queue.
++ * E.g. even if the vCPU handles the item in the "normal" path, the VM
++ * could be terminated before async_pf_execute() completes.
++ *
++ * Wake all events skip the queue and go straight done, i.e. don't
++ * need to be flushed (but sanity check that the work wasn't queued).
++ */
++ if (work->wakeup_all)
++ WARN_ON_ONCE(work->work.func);
++ else
++ flush_work(&work->work);
++ kmem_cache_free(async_pf_cache, work);
+ }
+
+ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu)
+@@ -125,7 +145,6 @@ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu)
+ #else
+ if (cancel_work_sync(&work->work)) {
+ mmput(work->mm);
+- kvm_put_kvm(vcpu->kvm); /* == work->vcpu->kvm */
+ kmem_cache_free(async_pf_cache, work);
+ }
+ #endif
+@@ -137,7 +156,10 @@ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu)
+ list_first_entry(&vcpu->async_pf.done,
+ typeof(*work), link);
+ list_del(&work->link);
+- kmem_cache_free(async_pf_cache, work);
++
++ spin_unlock(&vcpu->async_pf.lock);
++ kvm_flush_and_free_async_pf_work(work);
++ spin_lock(&vcpu->async_pf.lock);
+ }
+ spin_unlock(&vcpu->async_pf.lock);
+
+@@ -161,7 +183,7 @@ void kvm_check_async_pf_completion(struct kvm_vcpu *vcpu)
+
+ list_del(&work->queue);
+ vcpu->async_pf.queued--;
+- kmem_cache_free(async_pf_cache, work);
++ kvm_flush_and_free_async_pf_work(work);
+ }
+ }
+
+@@ -190,7 +212,6 @@ int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
+ work->arch = *arch;
+ work->mm = current->mm;
+ mmget(work->mm);
+- kvm_get_kvm(work->vcpu->kvm);
+
+ /* this can't really happen otherwise gfn_to_pfn_async
+ would succeed */
+--
+2.43.0
+
--- /dev/null
+From a2f1dfa244689b068b46c0f5accf458ff15bed02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jan 2024 17:09:09 +0900
+Subject: media: staging: ipu3-imgu: Set fields before media_entity_pads_init()
+
+From: Hidenori Kobayashi <hidenorik@chromium.org>
+
+[ Upstream commit 87318b7092670d4086bfec115a0280a60c51c2dd ]
+
+The imgu driver fails to probe with the following message because it
+does not set the pad's flags before calling media_entity_pads_init().
+
+[ 14.596315] ipu3-imgu 0000:00:05.0: failed initialize subdev media entity (-22)
+[ 14.596322] ipu3-imgu 0000:00:05.0: failed to register subdev0 ret (-22)
+[ 14.596327] ipu3-imgu 0000:00:05.0: failed to register pipes (-22)
+[ 14.596331] ipu3-imgu 0000:00:05.0: failed to create V4L2 devices (-22)
+
+Fix the initialization order so that the driver probe succeeds. The ops
+initialization is also moved together for readability.
+
+Fixes: a0ca1627b450 ("media: staging/intel-ipu3: Add v4l2 driver based on media framework")
+Cc: <stable@vger.kernel.org> # 6.7
+Cc: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Hidenori Kobayashi <hidenorik@chromium.org>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/media/ipu3/ipu3-v4l2.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c
+index 53239ea67fe48..ee9fed6fc67e9 100644
+--- a/drivers/staging/media/ipu3/ipu3-v4l2.c
++++ b/drivers/staging/media/ipu3/ipu3-v4l2.c
+@@ -1115,6 +1115,11 @@ static int imgu_v4l2_subdev_register(struct imgu_device *imgu,
+ struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe];
+
+ /* Initialize subdev media entity */
++ imgu_sd->subdev.entity.ops = &imgu_media_ops;
++ for (i = 0; i < IMGU_NODE_NUM; i++) {
++ imgu_sd->subdev_pads[i].flags = imgu_pipe->nodes[i].output ?
++ MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
++ }
+ r = media_entity_pads_init(&imgu_sd->subdev.entity, IMGU_NODE_NUM,
+ imgu_sd->subdev_pads);
+ if (r) {
+@@ -1122,11 +1127,6 @@ static int imgu_v4l2_subdev_register(struct imgu_device *imgu,
+ "failed initialize subdev media entity (%d)\n", r);
+ return r;
+ }
+- imgu_sd->subdev.entity.ops = &imgu_media_ops;
+- for (i = 0; i < IMGU_NODE_NUM; i++) {
+- imgu_sd->subdev_pads[i].flags = imgu_pipe->nodes[i].output ?
+- MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
+- }
+
+ /* Initialize subdev */
+ v4l2_subdev_init(&imgu_sd->subdev, &imgu_subdev_ops);
+@@ -1221,15 +1221,15 @@ static int imgu_v4l2_node_setup(struct imgu_device *imgu, unsigned int pipe,
+ }
+
+ /* Initialize media entities */
++ node->vdev_pad.flags = node->output ?
++ MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK;
++ vdev->entity.ops = NULL;
+ r = media_entity_pads_init(&vdev->entity, 1, &node->vdev_pad);
+ if (r) {
+ dev_err(dev, "failed initialize media entity (%d)\n", r);
+ mutex_destroy(&node->lock);
+ return r;
+ }
+- node->vdev_pad.flags = node->output ?
+- MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK;
+- vdev->entity.ops = NULL;
+
+ /* Initialize vbq */
+ vbq->type = node->vdev_fmt.type;
+--
+2.43.0
+
--- /dev/null
+From 0c88ec0ac6041bc08c8d293c554441b64d39eb7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Dec 2023 13:50:30 +0800
+Subject: media: xc4000: Fix atomicity violation in xc4000_get_frequency
+
+From: Gui-Dong Han <2045gemini@gmail.com>
+
+[ Upstream commit 36d503ad547d1c75758a6fcdbec2806f1b6aeb41 ]
+
+In xc4000_get_frequency():
+ *freq = priv->freq_hz + priv->freq_offset;
+The code accesses priv->freq_hz and priv->freq_offset without holding any
+lock.
+
+In xc4000_set_params():
+ // Code that updates priv->freq_hz and priv->freq_offset
+ ...
+
+xc4000_get_frequency() and xc4000_set_params() may execute concurrently,
+risking inconsistent reads of priv->freq_hz and priv->freq_offset. Since
+these related data may update during reading, it can result in incorrect
+frequency calculation, leading to atomicity violations.
+
+This possible bug is found by an experimental static analysis tool
+developed by our team, BassCheck[1]. This tool analyzes the locking APIs
+to extract function pairs that can be concurrently executed, and then
+analyzes the instructions in the paired functions to identify possible
+concurrency bugs including data races and atomicity violations. The above
+possible bug is reported when our tool analyzes the source code of
+Linux 6.2.
+
+To address this issue, it is proposed to add a mutex lock pair in
+xc4000_get_frequency() to ensure atomicity. With this patch applied, our
+tool no longer reports the possible bug, with the kernel configuration
+allyesconfig for x86_64. Due to the lack of associated hardware, we cannot
+test the patch in runtime testing, and just verify it according to the
+code logic.
+
+[1] https://sites.google.com/view/basscheck/
+
+Fixes: 4c07e32884ab ("[media] xc4000: Fix get_frequency()")
+Cc: stable@vger.kernel.org
+Reported-by: BassCheck <bass@buaa.edu.cn>
+Signed-off-by: Gui-Dong Han <2045gemini@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/media/tuners/xc4000.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/tuners/xc4000.c b/drivers/media/tuners/xc4000.c
+index ef9af052007cb..849df4d1c573c 100644
+--- a/drivers/media/tuners/xc4000.c
++++ b/drivers/media/tuners/xc4000.c
+@@ -1517,10 +1517,10 @@ static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
+ {
+ struct xc4000_priv *priv = fe->tuner_priv;
+
++ mutex_lock(&priv->lock);
+ *freq = priv->freq_hz + priv->freq_offset;
+
+ if (debug) {
+- mutex_lock(&priv->lock);
+ if ((priv->cur_fw.type
+ & (BASE | FM | DTV6 | DTV7 | DTV78 | DTV8)) == BASE) {
+ u16 snr = 0;
+@@ -1531,8 +1531,8 @@ static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
+ return 0;
+ }
+ }
+- mutex_unlock(&priv->lock);
+ }
++ mutex_unlock(&priv->lock);
+
+ dprintk(1, "%s()\n", __func__);
+
+--
+2.43.0
+
--- /dev/null
+From ccf953f57b1fe9b58efd8a8e3713ba3928c410d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Mar 2024 16:04:23 +0800
+Subject: memtest: use {READ,WRITE}_ONCE in memory scanning
+
+From: Qiang Zhang <qiang4.zhang@intel.com>
+
+[ Upstream commit 82634d7e24271698e50a3ec811e5f50de790a65f ]
+
+memtest failed to find bad memory when compiled with clang. So use
+{WRITE,READ}_ONCE to access memory to avoid compiler over optimization.
+
+Link: https://lkml.kernel.org/r/20240312080422.691222-1-qiang4.zhang@intel.com
+Signed-off-by: Qiang Zhang <qiang4.zhang@intel.com>
+Cc: Bill Wendling <morbo@google.com>
+Cc: Justin Stitt <justinstitt@google.com>
+Cc: Nathan Chancellor <nathan@kernel.org>
+Cc: Nick Desaulniers <ndesaulniers@google.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/memtest.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/mm/memtest.c b/mm/memtest.c
+index f53ace709ccd8..d407373f225b4 100644
+--- a/mm/memtest.c
++++ b/mm/memtest.c
+@@ -46,10 +46,10 @@ static void __init memtest(u64 pattern, phys_addr_t start_phys, phys_addr_t size
+ last_bad = 0;
+
+ for (p = start; p < end; p++)
+- *p = pattern;
++ WRITE_ONCE(*p, pattern);
+
+ for (p = start; p < end; p++, start_phys_aligned += incr) {
+- if (*p == pattern)
++ if (READ_ONCE(*p) == pattern)
+ continue;
+ if (start_phys_aligned == last_bad + incr) {
+ last_bad += incr;
+--
+2.43.0
+
--- /dev/null
+From f5db3108a2ca65dcfeff70e362b62f06b3306d84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Mar 2024 10:44:38 +0900
+Subject: mmc: core: Fix switch on gp3 partition
+
+From: Dominique Martinet <dominique.martinet@atmark-techno.com>
+
+[ Upstream commit 4af59a8df5ea930038cd3355e822f5eedf4accc1 ]
+
+Commit e7794c14fd73 ("mmc: rpmb: fixes pause retune on all RPMB
+partitions.") added a mask check for 'part_type', but the mask used was
+wrong leading to the code intended for rpmb also being executed for GP3.
+
+On some MMCs (but not all) this would make gp3 partition inaccessible:
+armadillo:~# head -c 1 < /dev/mmcblk2gp3
+head: standard input: I/O error
+armadillo:~# dmesg -c
+[ 422.976583] mmc2: running CQE recovery
+[ 423.058182] mmc2: running CQE recovery
+[ 423.137607] mmc2: running CQE recovery
+[ 423.137802] blk_update_request: I/O error, dev mmcblk2gp3, sector 0 op 0x0:(READ) flags 0x80700 phys_seg 4 prio class 0
+[ 423.237125] mmc2: running CQE recovery
+[ 423.318206] mmc2: running CQE recovery
+[ 423.397680] mmc2: running CQE recovery
+[ 423.397837] blk_update_request: I/O error, dev mmcblk2gp3, sector 0 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0
+[ 423.408287] Buffer I/O error on dev mmcblk2gp3, logical block 0, async page read
+
+the part_type values of interest here are defined as follow:
+main 0
+boot0 1
+boot1 2
+rpmb 3
+gp0 4
+gp1 5
+gp2 6
+gp3 7
+
+so mask with EXT_CSD_PART_CONFIG_ACC_MASK (7) to correctly identify rpmb
+
+Fixes: e7794c14fd73 ("mmc: rpmb: fixes pause retune on all RPMB partitions.")
+Cc: stable@vger.kernel.org
+Cc: Jorge Ramirez-Ortiz <jorge@foundries.io>
+Signed-off-by: Dominique Martinet <dominique.martinet@atmark-techno.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20240306-mmc-partswitch-v1-1-bf116985d950@codewreck.org
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/core/block.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
+index 554dba0a06f5b..32369b120f02c 100644
+--- a/drivers/mmc/core/block.c
++++ b/drivers/mmc/core/block.c
+@@ -873,10 +873,11 @@ static const struct block_device_operations mmc_bdops = {
+ static int mmc_blk_part_switch_pre(struct mmc_card *card,
+ unsigned int part_type)
+ {
+- const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_RPMB;
++ const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_MASK;
++ const unsigned int rpmb = EXT_CSD_PART_CONFIG_ACC_RPMB;
+ int ret = 0;
+
+- if ((part_type & mask) == mask) {
++ if ((part_type & mask) == rpmb) {
+ if (card->ext_csd.cmdq_en) {
+ ret = mmc_cmdq_disable(card);
+ if (ret)
+@@ -891,10 +892,11 @@ static int mmc_blk_part_switch_pre(struct mmc_card *card,
+ static int mmc_blk_part_switch_post(struct mmc_card *card,
+ unsigned int part_type)
+ {
+- const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_RPMB;
++ const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_MASK;
++ const unsigned int rpmb = EXT_CSD_PART_CONFIG_ACC_RPMB;
+ int ret = 0;
+
+- if ((part_type & mask) == mask) {
++ if ((part_type & mask) == rpmb) {
+ mmc_retune_unpause(card->host);
+ if (card->reenable_cmdq && !card->ext_csd.cmdq_en)
+ ret = mmc_cmdq_enable(card);
+--
+2.43.0
+
--- /dev/null
+From 75485efdd73b2ada183e77dc3d428b3315fd0fe0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 11:42:56 +0100
+Subject: mmc: tmio: avoid concurrent runs of mmc_request_done()
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit e8d1b41e69d72c62865bebe8f441163ec00b3d44 ]
+
+With the to-be-fixed commit, the reset_work handler cleared 'host->mrq'
+outside of the spinlock protected critical section. That leaves a small
+race window during execution of 'tmio_mmc_reset()' where the done_work
+handler could grab a pointer to the now invalid 'host->mrq'. Both would
+use it to call mmc_request_done() causing problems (see link below).
+
+However, 'host->mrq' cannot simply be cleared earlier inside the
+critical section. That would allow new mrqs to come in asynchronously
+while the actual reset of the controller still needs to be done. So,
+like 'tmio_mmc_set_ios()', an ERR_PTR is used to prevent new mrqs from
+coming in but still avoiding concurrency between work handlers.
+
+Reported-by: Dirk Behme <dirk.behme@de.bosch.com>
+Closes: https://lore.kernel.org/all/20240220061356.3001761-1-dirk.behme@de.bosch.com/
+Fixes: df3ef2d3c92c ("mmc: protect the tmio_mmc driver against a theoretical race")
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Tested-by: Dirk Behme <dirk.behme@de.bosch.com>
+Reviewed-by: Dirk Behme <dirk.behme@de.bosch.com>
+Cc: stable@vger.kernel.org # 3.0+
+Link: https://lore.kernel.org/r/20240305104423.3177-2-wsa+renesas@sang-engineering.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/host/tmio_mmc_core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
+index 25083f010a7ad..e21907b92cf11 100644
+--- a/drivers/mmc/host/tmio_mmc_core.c
++++ b/drivers/mmc/host/tmio_mmc_core.c
+@@ -217,6 +217,8 @@ static void tmio_mmc_reset_work(struct work_struct *work)
+ else
+ mrq->cmd->error = -ETIMEDOUT;
+
++ /* No new calls yet, but disallow concurrent tmio_mmc_done_work() */
++ host->mrq = ERR_PTR(-EBUSY);
+ host->cmd = NULL;
+ host->data = NULL;
+
+--
+2.43.0
+
--- /dev/null
+From 067a8169209a2ca5e037b19eafdfc5fe195da7af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Feb 2024 00:45:51 +0300
+Subject: mtd: rawnand: meson: fix scrambling mode value in command macro
+
+From: Arseniy Krasnov <avkrasnov@salutedevices.com>
+
+[ Upstream commit ef6f463599e16924cdd02ce5056ab52879dc008c ]
+
+Scrambling mode is enabled by value (1 << 19). NFC_CMD_SCRAMBLER_ENABLE
+is already (1 << 19), so there is no need to shift it again in CMDRWGEN
+macro.
+
+Signed-off-by: Arseniy Krasnov <avkrasnov@salutedevices.com>
+Cc: <Stable@vger.kernel.org>
+Fixes: 8fae856c5350 ("mtd: rawnand: meson: add support for Amlogic NAND flash controller")
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20240210214551.441610-1-avkrasnov@salutedevices.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/nand/raw/meson_nand.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
+index 29f3d39138e84..794c85cf22fa9 100644
+--- a/drivers/mtd/nand/raw/meson_nand.c
++++ b/drivers/mtd/nand/raw/meson_nand.c
+@@ -59,7 +59,7 @@
+ #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages) \
+ ( \
+ (cmd_dir) | \
+- ((ran) << 19) | \
++ (ran) | \
+ ((bch) << 14) | \
+ ((short_mode) << 13) | \
+ (((page_size) & 0x7f) << 6) | \
+--
+2.43.0
+
--- /dev/null
+From 7d462f1ebda9c4988ce2f4f610ca51de714d29ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Mar 2024 19:58:26 +0900
+Subject: nilfs2: fix failure to detect DAT corruption in btree and direct
+ mappings
+
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+
+[ Upstream commit f2f26b4a84a0ef41791bd2d70861c8eac748f4ba ]
+
+Patch series "nilfs2: fix kernel bug at submit_bh_wbc()".
+
+This resolves a kernel BUG reported by syzbot. Since there are two
+flaws involved, I've made each one a separate patch.
+
+The first patch alone resolves the syzbot-reported bug, but I think
+both fixes should be sent to stable, so I've tagged them as such.
+
+This patch (of 2):
+
+Syzbot has reported a kernel bug in submit_bh_wbc() when writing file data
+to a nilfs2 file system whose metadata is corrupted.
+
+There are two flaws involved in this issue.
+
+The first flaw is that when nilfs_get_block() locates a data block using
+btree or direct mapping, if the disk address translation routine
+nilfs_dat_translate() fails with internal code -ENOENT due to DAT metadata
+corruption, it can be passed back to nilfs_get_block(). This causes
+nilfs_get_block() to misidentify an existing block as non-existent,
+causing both data block lookup and insertion to fail inconsistently.
+
+The second flaw is that nilfs_get_block() returns a successful status in
+this inconsistent state. This causes the caller __block_write_begin_int()
+or others to request a read even though the buffer is not mapped,
+resulting in a BUG_ON check for the BH_Mapped flag in submit_bh_wbc()
+failing.
+
+This fixes the first issue by changing the return value to code -EINVAL
+when a conversion using DAT fails with code -ENOENT, avoiding the
+conflicting condition that leads to the kernel bug described above. Here,
+code -EINVAL indicates that metadata corruption was detected during the
+block lookup, which will be properly handled as a file system error and
+converted to -EIO when passing through the nilfs2 bmap layer.
+
+Link: https://lkml.kernel.org/r/20240313105827.5296-1-konishi.ryusuke@gmail.com
+Link: https://lkml.kernel.org/r/20240313105827.5296-2-konishi.ryusuke@gmail.com
+Fixes: c3a7abf06ce7 ("nilfs2: support contiguous lookup of blocks")
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Reported-by: syzbot+cfed5b56649bddf80d6e@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=cfed5b56649bddf80d6e
+Tested-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nilfs2/btree.c | 9 +++++++--
+ fs/nilfs2/direct.c | 9 +++++++--
+ 2 files changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
+index a0e37530dcf30..1ab5db17e8248 100644
+--- a/fs/nilfs2/btree.c
++++ b/fs/nilfs2/btree.c
+@@ -724,7 +724,7 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *btree,
+ dat = nilfs_bmap_get_dat(btree);
+ ret = nilfs_dat_translate(dat, ptr, &blocknr);
+ if (ret < 0)
+- goto out;
++ goto dat_error;
+ ptr = blocknr;
+ }
+ cnt = 1;
+@@ -743,7 +743,7 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *btree,
+ if (dat) {
+ ret = nilfs_dat_translate(dat, ptr2, &blocknr);
+ if (ret < 0)
+- goto out;
++ goto dat_error;
+ ptr2 = blocknr;
+ }
+ if (ptr2 != ptr + cnt || ++cnt == maxblocks)
+@@ -782,6 +782,11 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *btree,
+ out:
+ nilfs_btree_free_path(path);
+ return ret;
++
++ dat_error:
++ if (ret == -ENOENT)
++ ret = -EINVAL; /* Notify bmap layer of metadata corruption */
++ goto out;
+ }
+
+ static void nilfs_btree_promote_key(struct nilfs_bmap *btree,
+diff --git a/fs/nilfs2/direct.c b/fs/nilfs2/direct.c
+index 533e24ea3a88d..8d769c5dd5dc6 100644
+--- a/fs/nilfs2/direct.c
++++ b/fs/nilfs2/direct.c
+@@ -66,7 +66,7 @@ static int nilfs_direct_lookup_contig(const struct nilfs_bmap *direct,
+ dat = nilfs_bmap_get_dat(direct);
+ ret = nilfs_dat_translate(dat, ptr, &blocknr);
+ if (ret < 0)
+- return ret;
++ goto dat_error;
+ ptr = blocknr;
+ }
+
+@@ -79,7 +79,7 @@ static int nilfs_direct_lookup_contig(const struct nilfs_bmap *direct,
+ if (dat) {
+ ret = nilfs_dat_translate(dat, ptr2, &blocknr);
+ if (ret < 0)
+- return ret;
++ goto dat_error;
+ ptr2 = blocknr;
+ }
+ if (ptr2 != ptr + cnt)
+@@ -87,6 +87,11 @@ static int nilfs_direct_lookup_contig(const struct nilfs_bmap *direct,
+ }
+ *ptrp = ptr;
+ return cnt;
++
++ dat_error:
++ if (ret == -ENOENT)
++ ret = -EINVAL; /* Notify bmap layer of metadata corruption */
++ return ret;
+ }
+
+ static __u64
+--
+2.43.0
+
--- /dev/null
+From 1f3b327beb694b246665b1ff2f2c62038ae04843 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Mar 2024 19:58:27 +0900
+Subject: nilfs2: prevent kernel bug at submit_bh_wbc()
+
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+
+[ Upstream commit 269cdf353b5bdd15f1a079671b0f889113865f20 ]
+
+Fix a bug where nilfs_get_block() returns a successful status when
+searching and inserting the specified block both fail inconsistently. If
+this inconsistent behavior is not due to a previously fixed bug, then an
+unexpected race is occurring, so return a temporary error -EAGAIN instead.
+
+This prevents callers such as __block_write_begin_int() from requesting a
+read into a buffer that is not mapped, which would cause the BUG_ON check
+for the BH_Mapped flag in submit_bh_wbc() to fail.
+
+Link: https://lkml.kernel.org/r/20240313105827.5296-3-konishi.ryusuke@gmail.com
+Fixes: 1f5abe7e7dbc ("nilfs2: replace BUG_ON and BUG calls triggerable from ioctl")
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nilfs2/inode.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
+index 83dbfd9d25323..530edb813add8 100644
+--- a/fs/nilfs2/inode.c
++++ b/fs/nilfs2/inode.c
+@@ -111,7 +111,7 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff,
+ "%s (ino=%lu): a race condition while inserting a data block at offset=%llu",
+ __func__, inode->i_ino,
+ (unsigned long long)blkoff);
+- err = 0;
++ err = -EAGAIN;
+ }
+ nilfs_transaction_abort(inode->i_sb);
+ goto out;
+--
+2.43.0
+
--- /dev/null
+From 52a357f45d469d6c516573386d4b44ad1b857c3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Aug 2020 18:35:49 -0700
+Subject: nilfs2: use a more common logging style
+
+From: Joe Perches <joe@perches.com>
+
+[ Upstream commit a1d0747a393a079631130d61faa2a61027d1c789 ]
+
+Add macros for nilfs_<level>(sb, fmt, ...) and convert the uses of
+'nilfs_msg(sb, KERN_<LEVEL>, ...)' to 'nilfs_<level>(sb, ...)' so nilfs2
+uses a logging style more like the typical kernel logging style.
+
+Miscellanea:
+
+o Realign arguments for these uses
+
+Signed-off-by: Joe Perches <joe@perches.com>
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Link: http://lkml.kernel.org/r/1595860111-3920-4-git-send-email-konishi.ryusuke@gmail.com
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Stable-dep-of: 269cdf353b5b ("nilfs2: prevent kernel bug at submit_bh_wbc()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nilfs2/alloc.c | 38 +++++++++----------
+ fs/nilfs2/btree.c | 42 ++++++++++-----------
+ fs/nilfs2/cpfile.c | 10 ++---
+ fs/nilfs2/dat.c | 14 +++----
+ fs/nilfs2/direct.c | 14 ++++---
+ fs/nilfs2/gcinode.c | 2 +-
+ fs/nilfs2/ifile.c | 4 +-
+ fs/nilfs2/inode.c | 29 +++++++--------
+ fs/nilfs2/ioctl.c | 37 +++++++++----------
+ fs/nilfs2/mdt.c | 2 +-
+ fs/nilfs2/namei.c | 6 +--
+ fs/nilfs2/nilfs.h | 9 +++++
+ fs/nilfs2/page.c | 11 +++---
+ fs/nilfs2/recovery.c | 32 +++++++---------
+ fs/nilfs2/segbuf.c | 2 +-
+ fs/nilfs2/segment.c | 38 +++++++++----------
+ fs/nilfs2/sufile.c | 29 +++++++--------
+ fs/nilfs2/super.c | 57 ++++++++++++++---------------
+ fs/nilfs2/sysfs.c | 29 +++++++--------
+ fs/nilfs2/the_nilfs.c | 85 ++++++++++++++++++++-----------------------
+ 20 files changed, 239 insertions(+), 251 deletions(-)
+
+diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c
+index bbd82f650e93e..279d945d4ebee 100644
+--- a/fs/nilfs2/alloc.c
++++ b/fs/nilfs2/alloc.c
+@@ -614,10 +614,10 @@ void nilfs_palloc_commit_free_entry(struct inode *inode,
+ lock = nilfs_mdt_bgl_lock(inode, group);
+
+ if (!nilfs_clear_bit_atomic(lock, group_offset, bitmap))
+- nilfs_msg(inode->i_sb, KERN_WARNING,
+- "%s (ino=%lu): entry number %llu already freed",
+- __func__, inode->i_ino,
+- (unsigned long long)req->pr_entry_nr);
++ nilfs_warn(inode->i_sb,
++ "%s (ino=%lu): entry number %llu already freed",
++ __func__, inode->i_ino,
++ (unsigned long long)req->pr_entry_nr);
+ else
+ nilfs_palloc_group_desc_add_entries(desc, lock, 1);
+
+@@ -655,10 +655,10 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode,
+ lock = nilfs_mdt_bgl_lock(inode, group);
+
+ if (!nilfs_clear_bit_atomic(lock, group_offset, bitmap))
+- nilfs_msg(inode->i_sb, KERN_WARNING,
+- "%s (ino=%lu): entry number %llu already freed",
+- __func__, inode->i_ino,
+- (unsigned long long)req->pr_entry_nr);
++ nilfs_warn(inode->i_sb,
++ "%s (ino=%lu): entry number %llu already freed",
++ __func__, inode->i_ino,
++ (unsigned long long)req->pr_entry_nr);
+ else
+ nilfs_palloc_group_desc_add_entries(desc, lock, 1);
+
+@@ -764,10 +764,10 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
+ do {
+ if (!nilfs_clear_bit_atomic(lock, group_offset,
+ bitmap)) {
+- nilfs_msg(inode->i_sb, KERN_WARNING,
+- "%s (ino=%lu): entry number %llu already freed",
+- __func__, inode->i_ino,
+- (unsigned long long)entry_nrs[j]);
++ nilfs_warn(inode->i_sb,
++ "%s (ino=%lu): entry number %llu already freed",
++ __func__, inode->i_ino,
++ (unsigned long long)entry_nrs[j]);
+ } else {
+ n++;
+ }
+@@ -809,10 +809,10 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
+ ret = nilfs_palloc_delete_entry_block(inode,
+ last_nrs[k]);
+ if (ret && ret != -ENOENT)
+- nilfs_msg(inode->i_sb, KERN_WARNING,
+- "error %d deleting block that object (entry=%llu, ino=%lu) belongs to",
+- ret, (unsigned long long)last_nrs[k],
+- inode->i_ino);
++ nilfs_warn(inode->i_sb,
++ "error %d deleting block that object (entry=%llu, ino=%lu) belongs to",
++ ret, (unsigned long long)last_nrs[k],
++ inode->i_ino);
+ }
+
+ desc_kaddr = kmap_atomic(desc_bh->b_page);
+@@ -827,9 +827,9 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
+ if (nfree == nilfs_palloc_entries_per_group(inode)) {
+ ret = nilfs_palloc_delete_bitmap_block(inode, group);
+ if (ret && ret != -ENOENT)
+- nilfs_msg(inode->i_sb, KERN_WARNING,
+- "error %d deleting bitmap block of group=%lu, ino=%lu",
+- ret, group, inode->i_ino);
++ nilfs_warn(inode->i_sb,
++ "error %d deleting bitmap block of group=%lu, ino=%lu",
++ ret, group, inode->i_ino);
+ }
+ }
+ return 0;
+diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
+index 1ab5db17e8248..4905b7cd7bf33 100644
+--- a/fs/nilfs2/btree.c
++++ b/fs/nilfs2/btree.c
+@@ -352,10 +352,10 @@ static int nilfs_btree_node_broken(const struct nilfs_btree_node *node,
+ (flags & NILFS_BTREE_NODE_ROOT) ||
+ nchildren < 0 ||
+ nchildren > NILFS_BTREE_NODE_NCHILDREN_MAX(size))) {
+- nilfs_msg(inode->i_sb, KERN_CRIT,
+- "bad btree node (ino=%lu, blocknr=%llu): level = %d, flags = 0x%x, nchildren = %d",
+- inode->i_ino, (unsigned long long)blocknr, level,
+- flags, nchildren);
++ nilfs_crit(inode->i_sb,
++ "bad btree node (ino=%lu, blocknr=%llu): level = %d, flags = 0x%x, nchildren = %d",
++ inode->i_ino, (unsigned long long)blocknr, level,
++ flags, nchildren);
+ ret = 1;
+ }
+ return ret;
+@@ -382,9 +382,9 @@ static int nilfs_btree_root_broken(const struct nilfs_btree_node *node,
+ level >= NILFS_BTREE_LEVEL_MAX ||
+ nchildren < 0 ||
+ nchildren > NILFS_BTREE_ROOT_NCHILDREN_MAX)) {
+- nilfs_msg(inode->i_sb, KERN_CRIT,
+- "bad btree root (ino=%lu): level = %d, flags = 0x%x, nchildren = %d",
+- inode->i_ino, level, flags, nchildren);
++ nilfs_crit(inode->i_sb,
++ "bad btree root (ino=%lu): level = %d, flags = 0x%x, nchildren = %d",
++ inode->i_ino, level, flags, nchildren);
+ ret = 1;
+ }
+ return ret;
+@@ -451,10 +451,10 @@ static int nilfs_btree_bad_node(const struct nilfs_bmap *btree,
+ {
+ if (unlikely(nilfs_btree_node_get_level(node) != level)) {
+ dump_stack();
+- nilfs_msg(btree->b_inode->i_sb, KERN_CRIT,
+- "btree level mismatch (ino=%lu): %d != %d",
+- btree->b_inode->i_ino,
+- nilfs_btree_node_get_level(node), level);
++ nilfs_crit(btree->b_inode->i_sb,
++ "btree level mismatch (ino=%lu): %d != %d",
++ btree->b_inode->i_ino,
++ nilfs_btree_node_get_level(node), level);
+ return 1;
+ }
+ return 0;
+@@ -519,7 +519,7 @@ static int __nilfs_btree_get_block(const struct nilfs_bmap *btree, __u64 ptr,
+
+ out_no_wait:
+ if (!buffer_uptodate(bh)) {
+- nilfs_msg(btree->b_inode->i_sb, KERN_ERR,
++ nilfs_err(btree->b_inode->i_sb,
+ "I/O error reading b-tree node block (ino=%lu, blocknr=%llu)",
+ btree->b_inode->i_ino, (unsigned long long)ptr);
+ brelse(bh);
+@@ -2094,10 +2094,10 @@ static int nilfs_btree_propagate(struct nilfs_bmap *btree,
+ ret = nilfs_btree_do_lookup(btree, path, key, NULL, level + 1, 0);
+ if (ret < 0) {
+ if (unlikely(ret == -ENOENT))
+- nilfs_msg(btree->b_inode->i_sb, KERN_CRIT,
+- "writing node/leaf block does not appear in b-tree (ino=%lu) at key=%llu, level=%d",
+- btree->b_inode->i_ino,
+- (unsigned long long)key, level);
++ nilfs_crit(btree->b_inode->i_sb,
++ "writing node/leaf block does not appear in b-tree (ino=%lu) at key=%llu, level=%d",
++ btree->b_inode->i_ino,
++ (unsigned long long)key, level);
+ goto out;
+ }
+
+@@ -2134,11 +2134,11 @@ static void nilfs_btree_add_dirty_buffer(struct nilfs_bmap *btree,
+ if (level < NILFS_BTREE_LEVEL_NODE_MIN ||
+ level >= NILFS_BTREE_LEVEL_MAX) {
+ dump_stack();
+- nilfs_msg(btree->b_inode->i_sb, KERN_WARNING,
+- "invalid btree level: %d (key=%llu, ino=%lu, blocknr=%llu)",
+- level, (unsigned long long)key,
+- btree->b_inode->i_ino,
+- (unsigned long long)bh->b_blocknr);
++ nilfs_warn(btree->b_inode->i_sb,
++ "invalid btree level: %d (key=%llu, ino=%lu, blocknr=%llu)",
++ level, (unsigned long long)key,
++ btree->b_inode->i_ino,
++ (unsigned long long)bh->b_blocknr);
+ return;
+ }
+
+diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c
+index 8d41311b5db4b..86d4d850d1305 100644
+--- a/fs/nilfs2/cpfile.c
++++ b/fs/nilfs2/cpfile.c
+@@ -322,7 +322,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile,
+ int ret, ncps, nicps, nss, count, i;
+
+ if (unlikely(start == 0 || start > end)) {
+- nilfs_msg(cpfile->i_sb, KERN_ERR,
++ nilfs_err(cpfile->i_sb,
+ "cannot delete checkpoints: invalid range [%llu, %llu)",
+ (unsigned long long)start, (unsigned long long)end);
+ return -EINVAL;
+@@ -376,7 +376,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile,
+ cpfile, cno);
+ if (ret == 0)
+ continue;
+- nilfs_msg(cpfile->i_sb, KERN_ERR,
++ nilfs_err(cpfile->i_sb,
+ "error %d deleting checkpoint block",
+ ret);
+ break;
+@@ -981,12 +981,10 @@ int nilfs_cpfile_read(struct super_block *sb, size_t cpsize,
+ int err;
+
+ if (cpsize > sb->s_blocksize) {
+- nilfs_msg(sb, KERN_ERR,
+- "too large checkpoint size: %zu bytes", cpsize);
++ nilfs_err(sb, "too large checkpoint size: %zu bytes", cpsize);
+ return -EINVAL;
+ } else if (cpsize < NILFS_MIN_CHECKPOINT_SIZE) {
+- nilfs_msg(sb, KERN_ERR,
+- "too small checkpoint size: %zu bytes", cpsize);
++ nilfs_err(sb, "too small checkpoint size: %zu bytes", cpsize);
+ return -EINVAL;
+ }
+
+diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c
+index b9c759addd50e..c47e1f6f23a82 100644
+--- a/fs/nilfs2/dat.c
++++ b/fs/nilfs2/dat.c
+@@ -354,11 +354,11 @@ int nilfs_dat_move(struct inode *dat, __u64 vblocknr, sector_t blocknr)
+ kaddr = kmap_atomic(entry_bh->b_page);
+ entry = nilfs_palloc_block_get_entry(dat, vblocknr, entry_bh, kaddr);
+ if (unlikely(entry->de_blocknr == cpu_to_le64(0))) {
+- nilfs_msg(dat->i_sb, KERN_CRIT,
+- "%s: invalid vblocknr = %llu, [%llu, %llu)",
+- __func__, (unsigned long long)vblocknr,
+- (unsigned long long)le64_to_cpu(entry->de_start),
+- (unsigned long long)le64_to_cpu(entry->de_end));
++ nilfs_crit(dat->i_sb,
++ "%s: invalid vblocknr = %llu, [%llu, %llu)",
++ __func__, (unsigned long long)vblocknr,
++ (unsigned long long)le64_to_cpu(entry->de_start),
++ (unsigned long long)le64_to_cpu(entry->de_end));
+ kunmap_atomic(kaddr);
+ brelse(entry_bh);
+ return -EINVAL;
+@@ -485,11 +485,11 @@ int nilfs_dat_read(struct super_block *sb, size_t entry_size,
+ int err;
+
+ if (entry_size > sb->s_blocksize) {
+- nilfs_msg(sb, KERN_ERR, "too large DAT entry size: %zu bytes",
++ nilfs_err(sb, "too large DAT entry size: %zu bytes",
+ entry_size);
+ return -EINVAL;
+ } else if (entry_size < NILFS_MIN_DAT_ENTRY_SIZE) {
+- nilfs_msg(sb, KERN_ERR, "too small DAT entry size: %zu bytes",
++ nilfs_err(sb, "too small DAT entry size: %zu bytes",
+ entry_size);
+ return -EINVAL;
+ }
+diff --git a/fs/nilfs2/direct.c b/fs/nilfs2/direct.c
+index 8d769c5dd5dc6..7faf8c285d6c9 100644
+--- a/fs/nilfs2/direct.c
++++ b/fs/nilfs2/direct.c
+@@ -333,16 +333,18 @@ static int nilfs_direct_assign(struct nilfs_bmap *bmap,
+
+ key = nilfs_bmap_data_get_key(bmap, *bh);
+ if (unlikely(key > NILFS_DIRECT_KEY_MAX)) {
+- nilfs_msg(bmap->b_inode->i_sb, KERN_CRIT,
+- "%s (ino=%lu): invalid key: %llu", __func__,
+- bmap->b_inode->i_ino, (unsigned long long)key);
++ nilfs_crit(bmap->b_inode->i_sb,
++ "%s (ino=%lu): invalid key: %llu",
++ __func__,
++ bmap->b_inode->i_ino, (unsigned long long)key);
+ return -EINVAL;
+ }
+ ptr = nilfs_direct_get_ptr(bmap, key);
+ if (unlikely(ptr == NILFS_BMAP_INVALID_PTR)) {
+- nilfs_msg(bmap->b_inode->i_sb, KERN_CRIT,
+- "%s (ino=%lu): invalid pointer: %llu", __func__,
+- bmap->b_inode->i_ino, (unsigned long long)ptr);
++ nilfs_crit(bmap->b_inode->i_sb,
++ "%s (ino=%lu): invalid pointer: %llu",
++ __func__,
++ bmap->b_inode->i_ino, (unsigned long long)ptr);
+ return -EINVAL;
+ }
+
+diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c
+index cef46650102e7..b0077f5f71124 100644
+--- a/fs/nilfs2/gcinode.c
++++ b/fs/nilfs2/gcinode.c
+@@ -143,7 +143,7 @@ int nilfs_gccache_wait_and_mark_dirty(struct buffer_head *bh)
+ if (!buffer_uptodate(bh)) {
+ struct inode *inode = bh->b_page->mapping->host;
+
+- nilfs_msg(inode->i_sb, KERN_ERR,
++ nilfs_err(inode->i_sb,
+ "I/O error reading %s block for GC (ino=%lu, vblocknr=%llu)",
+ buffer_nilfs_node(bh) ? "node" : "data",
+ inode->i_ino, (unsigned long long)bh->b_blocknr);
+diff --git a/fs/nilfs2/ifile.c b/fs/nilfs2/ifile.c
+index 4140d232cadc0..02727ed3a7c6a 100644
+--- a/fs/nilfs2/ifile.c
++++ b/fs/nilfs2/ifile.c
+@@ -142,8 +142,8 @@ int nilfs_ifile_get_inode_block(struct inode *ifile, ino_t ino,
+
+ err = nilfs_palloc_get_entry_block(ifile, ino, 0, out_bh);
+ if (unlikely(err))
+- nilfs_msg(sb, KERN_WARNING, "error %d reading inode: ino=%lu",
+- err, (unsigned long)ino);
++ nilfs_warn(sb, "error %d reading inode: ino=%lu",
++ err, (unsigned long)ino);
+ return err;
+ }
+
+diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
+index ea94dc21af0c9..83dbfd9d25323 100644
+--- a/fs/nilfs2/inode.c
++++ b/fs/nilfs2/inode.c
+@@ -107,10 +107,10 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff,
+ * However, the page having this block must
+ * be locked in this case.
+ */
+- nilfs_msg(inode->i_sb, KERN_WARNING,
+- "%s (ino=%lu): a race condition while inserting a data block at offset=%llu",
+- __func__, inode->i_ino,
+- (unsigned long long)blkoff);
++ nilfs_warn(inode->i_sb,
++ "%s (ino=%lu): a race condition while inserting a data block at offset=%llu",
++ __func__, inode->i_ino,
++ (unsigned long long)blkoff);
+ err = 0;
+ }
+ nilfs_transaction_abort(inode->i_sb);
+@@ -862,9 +862,8 @@ static void nilfs_truncate_bmap(struct nilfs_inode_info *ii,
+ goto repeat;
+
+ failed:
+- nilfs_msg(ii->vfs_inode.i_sb, KERN_WARNING,
+- "error %d truncating bmap (ino=%lu)", ret,
+- ii->vfs_inode.i_ino);
++ nilfs_warn(ii->vfs_inode.i_sb, "error %d truncating bmap (ino=%lu)",
++ ret, ii->vfs_inode.i_ino);
+ }
+
+ void nilfs_truncate(struct inode *inode)
+@@ -1097,9 +1096,9 @@ int nilfs_set_file_dirty(struct inode *inode, unsigned int nr_dirty)
+ * This will happen when somebody is freeing
+ * this inode.
+ */
+- nilfs_msg(inode->i_sb, KERN_WARNING,
+- "cannot set file dirty (ino=%lu): the file is being freed",
+- inode->i_ino);
++ nilfs_warn(inode->i_sb,
++ "cannot set file dirty (ino=%lu): the file is being freed",
++ inode->i_ino);
+ spin_unlock(&nilfs->ns_inode_lock);
+ return -EINVAL; /*
+ * NILFS_I_DIRTY may remain for
+@@ -1128,9 +1127,9 @@ int __nilfs_mark_inode_dirty(struct inode *inode, int flags)
+
+ err = nilfs_load_inode_block(inode, &ibh);
+ if (unlikely(err)) {
+- nilfs_msg(inode->i_sb, KERN_WARNING,
+- "cannot mark inode dirty (ino=%lu): error %d loading inode block",
+- inode->i_ino, err);
++ nilfs_warn(inode->i_sb,
++ "cannot mark inode dirty (ino=%lu): error %d loading inode block",
++ inode->i_ino, err);
+ return err;
+ }
+ nilfs_update_inode(inode, ibh, flags);
+@@ -1156,8 +1155,8 @@ void nilfs_dirty_inode(struct inode *inode, int flags)
+ struct nilfs_mdt_info *mdi = NILFS_MDT(inode);
+
+ if (is_bad_inode(inode)) {
+- nilfs_msg(inode->i_sb, KERN_WARNING,
+- "tried to mark bad_inode dirty. ignored.");
++ nilfs_warn(inode->i_sb,
++ "tried to mark bad_inode dirty. ignored.");
+ dump_stack();
+ return;
+ }
+diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c
+index 83926b9ab4b59..1a266a10d4cf3 100644
+--- a/fs/nilfs2/ioctl.c
++++ b/fs/nilfs2/ioctl.c
+@@ -569,25 +569,25 @@ static int nilfs_ioctl_move_inode_block(struct inode *inode,
+
+ if (unlikely(ret < 0)) {
+ if (ret == -ENOENT)
+- nilfs_msg(inode->i_sb, KERN_CRIT,
+- "%s: invalid virtual block address (%s): ino=%llu, cno=%llu, offset=%llu, blocknr=%llu, vblocknr=%llu",
+- __func__, vdesc->vd_flags ? "node" : "data",
+- (unsigned long long)vdesc->vd_ino,
+- (unsigned long long)vdesc->vd_cno,
+- (unsigned long long)vdesc->vd_offset,
+- (unsigned long long)vdesc->vd_blocknr,
+- (unsigned long long)vdesc->vd_vblocknr);
++ nilfs_crit(inode->i_sb,
++ "%s: invalid virtual block address (%s): ino=%llu, cno=%llu, offset=%llu, blocknr=%llu, vblocknr=%llu",
++ __func__, vdesc->vd_flags ? "node" : "data",
++ (unsigned long long)vdesc->vd_ino,
++ (unsigned long long)vdesc->vd_cno,
++ (unsigned long long)vdesc->vd_offset,
++ (unsigned long long)vdesc->vd_blocknr,
++ (unsigned long long)vdesc->vd_vblocknr);
+ return ret;
+ }
+ if (unlikely(!list_empty(&bh->b_assoc_buffers))) {
+- nilfs_msg(inode->i_sb, KERN_CRIT,
+- "%s: conflicting %s buffer: ino=%llu, cno=%llu, offset=%llu, blocknr=%llu, vblocknr=%llu",
+- __func__, vdesc->vd_flags ? "node" : "data",
+- (unsigned long long)vdesc->vd_ino,
+- (unsigned long long)vdesc->vd_cno,
+- (unsigned long long)vdesc->vd_offset,
+- (unsigned long long)vdesc->vd_blocknr,
+- (unsigned long long)vdesc->vd_vblocknr);
++ nilfs_crit(inode->i_sb,
++ "%s: conflicting %s buffer: ino=%llu, cno=%llu, offset=%llu, blocknr=%llu, vblocknr=%llu",
++ __func__, vdesc->vd_flags ? "node" : "data",
++ (unsigned long long)vdesc->vd_ino,
++ (unsigned long long)vdesc->vd_cno,
++ (unsigned long long)vdesc->vd_offset,
++ (unsigned long long)vdesc->vd_blocknr,
++ (unsigned long long)vdesc->vd_vblocknr);
+ brelse(bh);
+ return -EEXIST;
+ }
+@@ -837,8 +837,7 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
+ return 0;
+
+ failed:
+- nilfs_msg(nilfs->ns_sb, KERN_ERR, "error %d preparing GC: %s", ret,
+- msg);
++ nilfs_err(nilfs->ns_sb, "error %d preparing GC: %s", ret, msg);
+ return ret;
+ }
+
+@@ -947,7 +946,7 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
+
+ ret = nilfs_ioctl_move_blocks(inode->i_sb, &argv[0], kbufs[0]);
+ if (ret < 0) {
+- nilfs_msg(inode->i_sb, KERN_ERR,
++ nilfs_err(inode->i_sb,
+ "error %d preparing GC: cannot read source blocks",
+ ret);
+ } else {
+diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
+index 7c9055d767d16..e80ef2c0a785c 100644
+--- a/fs/nilfs2/mdt.c
++++ b/fs/nilfs2/mdt.c
+@@ -199,7 +199,7 @@ static int nilfs_mdt_read_block(struct inode *inode, unsigned long block,
+ out_no_wait:
+ err = -EIO;
+ if (!buffer_uptodate(first_bh)) {
+- nilfs_msg(inode->i_sb, KERN_ERR,
++ nilfs_err(inode->i_sb,
+ "I/O error reading meta-data file (ino=%lu, block-offset=%lu)",
+ inode->i_ino, block);
+ goto failed_bh;
+diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
+index 9fe6d4ab74f01..a6ec7961d4f5a 100644
+--- a/fs/nilfs2/namei.c
++++ b/fs/nilfs2/namei.c
+@@ -272,9 +272,9 @@ static int nilfs_do_unlink(struct inode *dir, struct dentry *dentry)
+ goto out;
+
+ if (!inode->i_nlink) {
+- nilfs_msg(inode->i_sb, KERN_WARNING,
+- "deleting nonexistent file (ino=%lu), %d",
+- inode->i_ino, inode->i_nlink);
++ nilfs_warn(inode->i_sb,
++ "deleting nonexistent file (ino=%lu), %d",
++ inode->i_ino, inode->i_nlink);
+ set_nlink(inode, 1);
+ }
+ err = nilfs_delete_entry(de, page);
+diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
+index dc772eaa13cf1..6b9383ba0049d 100644
+--- a/fs/nilfs2/nilfs.h
++++ b/fs/nilfs2/nilfs.h
+@@ -319,6 +319,15 @@ void __nilfs_error(struct super_block *sb, const char *function,
+
+ #endif /* CONFIG_PRINTK */
+
++#define nilfs_crit(sb, fmt, ...) \
++ nilfs_msg(sb, KERN_CRIT, fmt, ##__VA_ARGS__)
++#define nilfs_err(sb, fmt, ...) \
++ nilfs_msg(sb, KERN_ERR, fmt, ##__VA_ARGS__)
++#define nilfs_warn(sb, fmt, ...) \
++ nilfs_msg(sb, KERN_WARNING, fmt, ##__VA_ARGS__)
++#define nilfs_info(sb, fmt, ...) \
++ nilfs_msg(sb, KERN_INFO, fmt, ##__VA_ARGS__)
++
+ extern struct nilfs_super_block *
+ nilfs_read_super_block(struct super_block *, u64, int, struct buffer_head **);
+ extern int nilfs_store_magic_and_option(struct super_block *,
+diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
+index 108e4528fccd0..fc86cc7a26d72 100644
+--- a/fs/nilfs2/page.c
++++ b/fs/nilfs2/page.c
+@@ -399,9 +399,8 @@ void nilfs_clear_dirty_page(struct page *page, bool silent)
+ BUG_ON(!PageLocked(page));
+
+ if (!silent)
+- nilfs_msg(sb, KERN_WARNING,
+- "discard dirty page: offset=%lld, ino=%lu",
+- page_offset(page), inode->i_ino);
++ nilfs_warn(sb, "discard dirty page: offset=%lld, ino=%lu",
++ page_offset(page), inode->i_ino);
+
+ ClearPageUptodate(page);
+ ClearPageMappedToDisk(page);
+@@ -417,9 +416,9 @@ void nilfs_clear_dirty_page(struct page *page, bool silent)
+ do {
+ lock_buffer(bh);
+ if (!silent)
+- nilfs_msg(sb, KERN_WARNING,
+- "discard dirty block: blocknr=%llu, size=%zu",
+- (u64)bh->b_blocknr, bh->b_size);
++ nilfs_warn(sb,
++ "discard dirty block: blocknr=%llu, size=%zu",
++ (u64)bh->b_blocknr, bh->b_size);
+
+ set_mask_bits(&bh->b_state, clear_bits, 0);
+ unlock_buffer(bh);
+diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c
+index 18feb9c7c7066..0923231e9e605 100644
+--- a/fs/nilfs2/recovery.c
++++ b/fs/nilfs2/recovery.c
+@@ -51,7 +51,7 @@ static int nilfs_warn_segment_error(struct super_block *sb, int err)
+
+ switch (err) {
+ case NILFS_SEG_FAIL_IO:
+- nilfs_msg(sb, KERN_ERR, "I/O error reading segment");
++ nilfs_err(sb, "I/O error reading segment");
+ return -EIO;
+ case NILFS_SEG_FAIL_MAGIC:
+ msg = "Magic number mismatch";
+@@ -72,10 +72,10 @@ static int nilfs_warn_segment_error(struct super_block *sb, int err)
+ msg = "No super root in the last segment";
+ break;
+ default:
+- nilfs_msg(sb, KERN_ERR, "unrecognized segment error %d", err);
++ nilfs_err(sb, "unrecognized segment error %d", err);
+ return -EINVAL;
+ }
+- nilfs_msg(sb, KERN_WARNING, "invalid segment: %s", msg);
++ nilfs_warn(sb, "invalid segment: %s", msg);
+ return -EINVAL;
+ }
+
+@@ -544,10 +544,10 @@ static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs,
+ put_page(page);
+
+ failed_inode:
+- nilfs_msg(sb, KERN_WARNING,
+- "error %d recovering data block (ino=%lu, block-offset=%llu)",
+- err, (unsigned long)rb->ino,
+- (unsigned long long)rb->blkoff);
++ nilfs_warn(sb,
++ "error %d recovering data block (ino=%lu, block-offset=%llu)",
++ err, (unsigned long)rb->ino,
++ (unsigned long long)rb->blkoff);
+ if (!err2)
+ err2 = err;
+ next:
+@@ -670,8 +670,7 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
+ }
+
+ if (nsalvaged_blocks) {
+- nilfs_msg(sb, KERN_INFO, "salvaged %lu blocks",
+- nsalvaged_blocks);
++ nilfs_info(sb, "salvaged %lu blocks", nsalvaged_blocks);
+ ri->ri_need_recovery = NILFS_RECOVERY_ROLLFORWARD_DONE;
+ }
+ out:
+@@ -682,7 +681,7 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
+ confused:
+ err = -EINVAL;
+ failed:
+- nilfs_msg(sb, KERN_ERR,
++ nilfs_err(sb,
+ "error %d roll-forwarding partial segment at blocknr = %llu",
+ err, (unsigned long long)pseg_start);
+ goto out;
+@@ -704,8 +703,8 @@ static void nilfs_finish_roll_forward(struct the_nilfs *nilfs,
+ set_buffer_dirty(bh);
+ err = sync_dirty_buffer(bh);
+ if (unlikely(err))
+- nilfs_msg(nilfs->ns_sb, KERN_WARNING,
+- "buffer sync write failed during post-cleaning of recovery.");
++ nilfs_warn(nilfs->ns_sb,
++ "buffer sync write failed during post-cleaning of recovery.");
+ brelse(bh);
+ }
+
+@@ -740,8 +739,7 @@ int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs,
+
+ err = nilfs_attach_checkpoint(sb, ri->ri_cno, true, &root);
+ if (unlikely(err)) {
+- nilfs_msg(sb, KERN_ERR,
+- "error %d loading the latest checkpoint", err);
++ nilfs_err(sb, "error %d loading the latest checkpoint", err);
+ return err;
+ }
+
+@@ -752,8 +750,7 @@ int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs,
+ if (ri->ri_need_recovery == NILFS_RECOVERY_ROLLFORWARD_DONE) {
+ err = nilfs_prepare_segment_for_recovery(nilfs, sb, ri);
+ if (unlikely(err)) {
+- nilfs_msg(sb, KERN_ERR,
+- "error %d preparing segment for recovery",
++ nilfs_err(sb, "error %d preparing segment for recovery",
+ err);
+ goto failed;
+ }
+@@ -767,8 +764,7 @@ int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs,
+ nilfs_detach_log_writer(sb);
+
+ if (unlikely(err)) {
+- nilfs_msg(sb, KERN_ERR,
+- "error %d writing segment for recovery",
++ nilfs_err(sb, "error %d writing segment for recovery",
+ err);
+ goto failed;
+ }
+diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c
+index e72466fc8ca93..9f435879a0487 100644
+--- a/fs/nilfs2/segbuf.c
++++ b/fs/nilfs2/segbuf.c
+@@ -511,7 +511,7 @@ static int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf)
+ } while (--segbuf->sb_nbio > 0);
+
+ if (unlikely(atomic_read(&segbuf->sb_err) > 0)) {
+- nilfs_msg(segbuf->sb_super, KERN_ERR,
++ nilfs_err(segbuf->sb_super,
+ "I/O error writing log (start-blocknr=%llu, block-count=%lu) in segment %llu",
+ (unsigned long long)segbuf->sb_pseg_start,
+ segbuf->sb_sum.nblocks,
+diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
+index 7d1860d33723e..d4610f71d21b7 100644
+--- a/fs/nilfs2/segment.c
++++ b/fs/nilfs2/segment.c
+@@ -158,7 +158,7 @@ static int nilfs_prepare_segment_lock(struct super_block *sb,
+ * it is saved and will be restored on
+ * nilfs_transaction_commit().
+ */
+- nilfs_msg(sb, KERN_WARNING, "journal info from a different FS");
++ nilfs_warn(sb, "journal info from a different FS");
+ save = current->journal_info;
+ }
+ if (!ti) {
+@@ -1983,9 +1983,9 @@ static int nilfs_segctor_collect_dirty_files(struct nilfs_sc_info *sci,
+ err = nilfs_ifile_get_inode_block(
+ ifile, ii->vfs_inode.i_ino, &ibh);
+ if (unlikely(err)) {
+- nilfs_msg(sci->sc_super, KERN_WARNING,
+- "log writer: error %d getting inode block (ino=%lu)",
+- err, ii->vfs_inode.i_ino);
++ nilfs_warn(sci->sc_super,
++ "log writer: error %d getting inode block (ino=%lu)",
++ err, ii->vfs_inode.i_ino);
+ return err;
+ }
+ spin_lock(&nilfs->ns_inode_lock);
+@@ -2495,7 +2495,7 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,
+ if (likely(!err))
+ break;
+
+- nilfs_msg(sb, KERN_WARNING, "error %d cleaning segments", err);
++ nilfs_warn(sb, "error %d cleaning segments", err);
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(sci->sc_interval);
+ }
+@@ -2503,9 +2503,9 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,
+ int ret = nilfs_discard_segments(nilfs, sci->sc_freesegs,
+ sci->sc_nfreesegs);
+ if (ret) {
+- nilfs_msg(sb, KERN_WARNING,
+- "error %d on discard request, turning discards off for the device",
+- ret);
++ nilfs_warn(sb,
++ "error %d on discard request, turning discards off for the device",
++ ret);
+ nilfs_clear_opt(nilfs, DISCARD);
+ }
+ }
+@@ -2586,9 +2586,9 @@ static int nilfs_segctor_thread(void *arg)
+ /* start sync. */
+ sci->sc_task = current;
+ wake_up(&sci->sc_wait_task); /* for nilfs_segctor_start_thread() */
+- nilfs_msg(sci->sc_super, KERN_INFO,
+- "segctord starting. Construction interval = %lu seconds, CP frequency < %lu seconds",
+- sci->sc_interval / HZ, sci->sc_mjcp_freq / HZ);
++ nilfs_info(sci->sc_super,
++ "segctord starting. Construction interval = %lu seconds, CP frequency < %lu seconds",
++ sci->sc_interval / HZ, sci->sc_mjcp_freq / HZ);
+
+ spin_lock(&sci->sc_state_lock);
+ loop:
+@@ -2661,8 +2661,8 @@ static int nilfs_segctor_start_thread(struct nilfs_sc_info *sci)
+ if (IS_ERR(t)) {
+ int err = PTR_ERR(t);
+
+- nilfs_msg(sci->sc_super, KERN_ERR,
+- "error %d creating segctord thread", err);
++ nilfs_err(sci->sc_super, "error %d creating segctord thread",
++ err);
+ return err;
+ }
+ wait_event(sci->sc_wait_task, sci->sc_task != NULL);
+@@ -2772,14 +2772,14 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
+ nilfs_segctor_write_out(sci);
+
+ if (!list_empty(&sci->sc_dirty_files)) {
+- nilfs_msg(sci->sc_super, KERN_WARNING,
+- "disposed unprocessed dirty file(s) when stopping log writer");
++ nilfs_warn(sci->sc_super,
++ "disposed unprocessed dirty file(s) when stopping log writer");
+ nilfs_dispose_list(nilfs, &sci->sc_dirty_files, 1);
+ }
+
+ if (!list_empty(&sci->sc_iput_queue)) {
+- nilfs_msg(sci->sc_super, KERN_WARNING,
+- "disposed unprocessed inode(s) in iput queue when stopping log writer");
++ nilfs_warn(sci->sc_super,
++ "disposed unprocessed inode(s) in iput queue when stopping log writer");
+ nilfs_dispose_list(nilfs, &sci->sc_iput_queue, 1);
+ }
+
+@@ -2858,8 +2858,8 @@ void nilfs_detach_log_writer(struct super_block *sb)
+ spin_lock(&nilfs->ns_inode_lock);
+ if (!list_empty(&nilfs->ns_dirty_files)) {
+ list_splice_init(&nilfs->ns_dirty_files, &garbage_list);
+- nilfs_msg(sb, KERN_WARNING,
+- "disposed unprocessed dirty file(s) when detaching log writer");
++ nilfs_warn(sb,
++ "disposed unprocessed dirty file(s) when detaching log writer");
+ }
+ spin_unlock(&nilfs->ns_inode_lock);
+ up_write(&nilfs->ns_segctor_sem);
+diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
+index 4626540008c13..379db0c54227f 100644
+--- a/fs/nilfs2/sufile.c
++++ b/fs/nilfs2/sufile.c
+@@ -171,9 +171,9 @@ int nilfs_sufile_updatev(struct inode *sufile, __u64 *segnumv, size_t nsegs,
+ down_write(&NILFS_MDT(sufile)->mi_sem);
+ for (seg = segnumv; seg < segnumv + nsegs; seg++) {
+ if (unlikely(*seg >= nilfs_sufile_get_nsegments(sufile))) {
+- nilfs_msg(sufile->i_sb, KERN_WARNING,
+- "%s: invalid segment number: %llu",
+- __func__, (unsigned long long)*seg);
++ nilfs_warn(sufile->i_sb,
++ "%s: invalid segment number: %llu",
++ __func__, (unsigned long long)*seg);
+ nerr++;
+ }
+ }
+@@ -230,9 +230,8 @@ int nilfs_sufile_update(struct inode *sufile, __u64 segnum, int create,
+ int ret;
+
+ if (unlikely(segnum >= nilfs_sufile_get_nsegments(sufile))) {
+- nilfs_msg(sufile->i_sb, KERN_WARNING,
+- "%s: invalid segment number: %llu",
+- __func__, (unsigned long long)segnum);
++ nilfs_warn(sufile->i_sb, "%s: invalid segment number: %llu",
++ __func__, (unsigned long long)segnum);
+ return -EINVAL;
+ }
+ down_write(&NILFS_MDT(sufile)->mi_sem);
+@@ -410,9 +409,8 @@ void nilfs_sufile_do_cancel_free(struct inode *sufile, __u64 segnum,
+ kaddr = kmap_atomic(su_bh->b_page);
+ su = nilfs_sufile_block_get_segment_usage(sufile, segnum, su_bh, kaddr);
+ if (unlikely(!nilfs_segment_usage_clean(su))) {
+- nilfs_msg(sufile->i_sb, KERN_WARNING,
+- "%s: segment %llu must be clean", __func__,
+- (unsigned long long)segnum);
++ nilfs_warn(sufile->i_sb, "%s: segment %llu must be clean",
++ __func__, (unsigned long long)segnum);
+ kunmap_atomic(kaddr);
+ return;
+ }
+@@ -468,9 +466,8 @@ void nilfs_sufile_do_free(struct inode *sufile, __u64 segnum,
+ kaddr = kmap_atomic(su_bh->b_page);
+ su = nilfs_sufile_block_get_segment_usage(sufile, segnum, su_bh, kaddr);
+ if (nilfs_segment_usage_clean(su)) {
+- nilfs_msg(sufile->i_sb, KERN_WARNING,
+- "%s: segment %llu is already clean",
+- __func__, (unsigned long long)segnum);
++ nilfs_warn(sufile->i_sb, "%s: segment %llu is already clean",
++ __func__, (unsigned long long)segnum);
+ kunmap_atomic(kaddr);
+ return;
+ }
+@@ -1213,12 +1210,12 @@ int nilfs_sufile_read(struct super_block *sb, size_t susize,
+ int err;
+
+ if (susize > sb->s_blocksize) {
+- nilfs_msg(sb, KERN_ERR,
+- "too large segment usage size: %zu bytes", susize);
++ nilfs_err(sb, "too large segment usage size: %zu bytes",
++ susize);
+ return -EINVAL;
+ } else if (susize < NILFS_MIN_SEGMENT_USAGE_SIZE) {
+- nilfs_msg(sb, KERN_ERR,
+- "too small segment usage size: %zu bytes", susize);
++ nilfs_err(sb, "too small segment usage size: %zu bytes",
++ susize);
+ return -EINVAL;
+ }
+
+diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
+index 2263ebedf9d58..59e74e764cd27 100644
+--- a/fs/nilfs2/super.c
++++ b/fs/nilfs2/super.c
+@@ -106,7 +106,7 @@ static void nilfs_set_error(struct super_block *sb)
+ *
+ * This implements the body of nilfs_error() macro. Normally,
+ * nilfs_error() should be used. As for sustainable errors such as a
+- * single-shot I/O error, nilfs_msg() should be used instead.
++ * single-shot I/O error, nilfs_err() should be used instead.
+ *
+ * Callers should not add a trailing newline since this will do it.
+ */
+@@ -179,8 +179,7 @@ static int nilfs_sync_super(struct super_block *sb, int flag)
+ }
+
+ if (unlikely(err)) {
+- nilfs_msg(sb, KERN_ERR, "unable to write superblock: err=%d",
+- err);
++ nilfs_err(sb, "unable to write superblock: err=%d", err);
+ if (err == -EIO && nilfs->ns_sbh[1]) {
+ /*
+ * sbp[0] points to newer log than sbp[1],
+@@ -250,7 +249,7 @@ struct nilfs_super_block **nilfs_prepare_super(struct super_block *sb,
+ sbp[1]->s_magic == cpu_to_le16(NILFS_SUPER_MAGIC)) {
+ memcpy(sbp[0], sbp[1], nilfs->ns_sbsize);
+ } else {
+- nilfs_msg(sb, KERN_CRIT, "superblock broke");
++ nilfs_crit(sb, "superblock broke");
+ return NULL;
+ }
+ } else if (sbp[1] &&
+@@ -360,9 +359,9 @@ static int nilfs_move_2nd_super(struct super_block *sb, loff_t sb2off)
+ offset = sb2off & (nilfs->ns_blocksize - 1);
+ nsbh = sb_getblk(sb, newblocknr);
+ if (!nsbh) {
+- nilfs_msg(sb, KERN_WARNING,
+- "unable to move secondary superblock to block %llu",
+- (unsigned long long)newblocknr);
++ nilfs_warn(sb,
++ "unable to move secondary superblock to block %llu",
++ (unsigned long long)newblocknr);
+ ret = -EIO;
+ goto out;
+ }
+@@ -556,7 +555,7 @@ int nilfs_attach_checkpoint(struct super_block *sb, __u64 cno, int curr_mnt,
+ up_read(&nilfs->ns_segctor_sem);
+ if (unlikely(err)) {
+ if (err == -ENOENT || err == -EINVAL) {
+- nilfs_msg(sb, KERN_ERR,
++ nilfs_err(sb,
+ "Invalid checkpoint (checkpoint number=%llu)",
+ (unsigned long long)cno);
+ err = -EINVAL;
+@@ -654,8 +653,7 @@ static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf)
+ err = nilfs_ifile_count_free_inodes(root->ifile,
+ &nmaxinodes, &nfreeinodes);
+ if (unlikely(err)) {
+- nilfs_msg(sb, KERN_WARNING,
+- "failed to count free inodes: err=%d", err);
++ nilfs_warn(sb, "failed to count free inodes: err=%d", err);
+ if (err == -ERANGE) {
+ /*
+ * If nilfs_palloc_count_max_entries() returns
+@@ -787,7 +785,7 @@ static int parse_options(char *options, struct super_block *sb, int is_remount)
+ break;
+ case Opt_snapshot:
+ if (is_remount) {
+- nilfs_msg(sb, KERN_ERR,
++ nilfs_err(sb,
+ "\"%s\" option is invalid for remount",
+ p);
+ return 0;
+@@ -803,8 +801,7 @@ static int parse_options(char *options, struct super_block *sb, int is_remount)
+ nilfs_clear_opt(nilfs, DISCARD);
+ break;
+ default:
+- nilfs_msg(sb, KERN_ERR,
+- "unrecognized mount option \"%s\"", p);
++ nilfs_err(sb, "unrecognized mount option \"%s\"", p);
+ return 0;
+ }
+ }
+@@ -840,10 +837,10 @@ static int nilfs_setup_super(struct super_block *sb, int is_mount)
+ mnt_count = le16_to_cpu(sbp[0]->s_mnt_count);
+
+ if (nilfs->ns_mount_state & NILFS_ERROR_FS) {
+- nilfs_msg(sb, KERN_WARNING, "mounting fs with errors");
++ nilfs_warn(sb, "mounting fs with errors");
+ #if 0
+ } else if (max_mnt_count >= 0 && mnt_count >= max_mnt_count) {
+- nilfs_msg(sb, KERN_WARNING, "maximal mount count reached");
++ nilfs_warn(sb, "maximal mount count reached");
+ #endif
+ }
+ if (!max_mnt_count)
+@@ -906,7 +903,7 @@ int nilfs_check_feature_compatibility(struct super_block *sb,
+ features = le64_to_cpu(sbp->s_feature_incompat) &
+ ~NILFS_FEATURE_INCOMPAT_SUPP;
+ if (features) {
+- nilfs_msg(sb, KERN_ERR,
++ nilfs_err(sb,
+ "couldn't mount because of unsupported optional features (%llx)",
+ (unsigned long long)features);
+ return -EINVAL;
+@@ -914,7 +911,7 @@ int nilfs_check_feature_compatibility(struct super_block *sb,
+ features = le64_to_cpu(sbp->s_feature_compat_ro) &
+ ~NILFS_FEATURE_COMPAT_RO_SUPP;
+ if (!sb_rdonly(sb) && features) {
+- nilfs_msg(sb, KERN_ERR,
++ nilfs_err(sb,
+ "couldn't mount RDWR because of unsupported optional features (%llx)",
+ (unsigned long long)features);
+ return -EINVAL;
+@@ -933,12 +930,12 @@ static int nilfs_get_root_dentry(struct super_block *sb,
+ inode = nilfs_iget(sb, root, NILFS_ROOT_INO);
+ if (IS_ERR(inode)) {
+ ret = PTR_ERR(inode);
+- nilfs_msg(sb, KERN_ERR, "error %d getting root inode", ret);
++ nilfs_err(sb, "error %d getting root inode", ret);
+ goto out;
+ }
+ if (!S_ISDIR(inode->i_mode) || !inode->i_blocks || !inode->i_size) {
+ iput(inode);
+- nilfs_msg(sb, KERN_ERR, "corrupt root inode");
++ nilfs_err(sb, "corrupt root inode");
+ ret = -EINVAL;
+ goto out;
+ }
+@@ -966,7 +963,7 @@ static int nilfs_get_root_dentry(struct super_block *sb,
+ return ret;
+
+ failed_dentry:
+- nilfs_msg(sb, KERN_ERR, "error %d getting root dentry", ret);
++ nilfs_err(sb, "error %d getting root dentry", ret);
+ goto out;
+ }
+
+@@ -986,7 +983,7 @@ static int nilfs_attach_snapshot(struct super_block *s, __u64 cno,
+ ret = (ret == -ENOENT) ? -EINVAL : ret;
+ goto out;
+ } else if (!ret) {
+- nilfs_msg(s, KERN_ERR,
++ nilfs_err(s,
+ "The specified checkpoint is not a snapshot (checkpoint number=%llu)",
+ (unsigned long long)cno);
+ ret = -EINVAL;
+@@ -995,7 +992,7 @@ static int nilfs_attach_snapshot(struct super_block *s, __u64 cno,
+
+ ret = nilfs_attach_checkpoint(s, cno, false, &root);
+ if (ret) {
+- nilfs_msg(s, KERN_ERR,
++ nilfs_err(s,
+ "error %d while loading snapshot (checkpoint number=%llu)",
+ ret, (unsigned long long)cno);
+ goto out;
+@@ -1092,7 +1089,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent)
+ cno = nilfs_last_cno(nilfs);
+ err = nilfs_attach_checkpoint(sb, cno, true, &fsroot);
+ if (err) {
+- nilfs_msg(sb, KERN_ERR,
++ nilfs_err(sb,
+ "error %d while loading last checkpoint (checkpoint number=%llu)",
+ err, (unsigned long long)cno);
+ goto failed_unload;
+@@ -1155,8 +1152,8 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
+ err = -EINVAL;
+
+ if (!nilfs_valid_fs(nilfs)) {
+- nilfs_msg(sb, KERN_WARNING,
+- "couldn't remount because the filesystem is in an incomplete recovery state");
++ nilfs_warn(sb,
++ "couldn't remount because the filesystem is in an incomplete recovery state");
+ goto restore_opts;
+ }
+
+@@ -1186,9 +1183,9 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
+ ~NILFS_FEATURE_COMPAT_RO_SUPP;
+ up_read(&nilfs->ns_sem);
+ if (features) {
+- nilfs_msg(sb, KERN_WARNING,
+- "couldn't remount RDWR because of unsupported optional features (%llx)",
+- (unsigned long long)features);
++ nilfs_warn(sb,
++ "couldn't remount RDWR because of unsupported optional features (%llx)",
++ (unsigned long long)features);
+ err = -EROFS;
+ goto restore_opts;
+ }
+@@ -1247,7 +1244,7 @@ static int nilfs_parse_snapshot_option(const char *option,
+ return 0;
+
+ parse_error:
+- nilfs_msg(NULL, KERN_ERR, "invalid option \"%s\": %s", option, msg);
++ nilfs_err(NULL, "invalid option \"%s\": %s", option, msg);
+ return 1;
+ }
+
+@@ -1350,7 +1347,7 @@ nilfs_mount(struct file_system_type *fs_type, int flags,
+ } else if (!sd.cno) {
+ if (nilfs_tree_is_busy(s->s_root)) {
+ if ((flags ^ s->s_flags) & SB_RDONLY) {
+- nilfs_msg(s, KERN_ERR,
++ nilfs_err(s,
+ "the device already has a %s mount.",
+ sb_rdonly(s) ? "read-only" : "read/write");
+ err = -EBUSY;
+diff --git a/fs/nilfs2/sysfs.c b/fs/nilfs2/sysfs.c
+index 28a2db3b1787f..57afd06db62de 100644
+--- a/fs/nilfs2/sysfs.c
++++ b/fs/nilfs2/sysfs.c
+@@ -261,8 +261,8 @@ nilfs_checkpoints_checkpoints_number_show(struct nilfs_checkpoints_attr *attr,
+ err = nilfs_cpfile_get_stat(nilfs->ns_cpfile, &cpstat);
+ up_read(&nilfs->ns_segctor_sem);
+ if (err < 0) {
+- nilfs_msg(nilfs->ns_sb, KERN_ERR,
+- "unable to get checkpoint stat: err=%d", err);
++ nilfs_err(nilfs->ns_sb, "unable to get checkpoint stat: err=%d",
++ err);
+ return err;
+ }
+
+@@ -284,8 +284,8 @@ nilfs_checkpoints_snapshots_number_show(struct nilfs_checkpoints_attr *attr,
+ err = nilfs_cpfile_get_stat(nilfs->ns_cpfile, &cpstat);
+ up_read(&nilfs->ns_segctor_sem);
+ if (err < 0) {
+- nilfs_msg(nilfs->ns_sb, KERN_ERR,
+- "unable to get checkpoint stat: err=%d", err);
++ nilfs_err(nilfs->ns_sb, "unable to get checkpoint stat: err=%d",
++ err);
+ return err;
+ }
+
+@@ -403,8 +403,8 @@ nilfs_segments_dirty_segments_show(struct nilfs_segments_attr *attr,
+ err = nilfs_sufile_get_stat(nilfs->ns_sufile, &sustat);
+ up_read(&nilfs->ns_segctor_sem);
+ if (err < 0) {
+- nilfs_msg(nilfs->ns_sb, KERN_ERR,
+- "unable to get segment stat: err=%d", err);
++ nilfs_err(nilfs->ns_sb, "unable to get segment stat: err=%d",
++ err);
+ return err;
+ }
+
+@@ -777,15 +777,15 @@ nilfs_superblock_sb_update_frequency_store(struct nilfs_superblock_attr *attr,
+
+ err = kstrtouint(skip_spaces(buf), 0, &val);
+ if (err) {
+- nilfs_msg(nilfs->ns_sb, KERN_ERR,
+- "unable to convert string: err=%d", err);
++ nilfs_err(nilfs->ns_sb, "unable to convert string: err=%d",
++ err);
+ return err;
+ }
+
+ if (val < NILFS_SB_FREQ) {
+ val = NILFS_SB_FREQ;
+- nilfs_msg(nilfs->ns_sb, KERN_WARNING,
+- "superblock update frequency cannot be lesser than 10 seconds");
++ nilfs_warn(nilfs->ns_sb,
++ "superblock update frequency cannot be lesser than 10 seconds");
+ }
+
+ down_write(&nilfs->ns_sem);
+@@ -988,8 +988,7 @@ int nilfs_sysfs_create_device_group(struct super_block *sb)
+ nilfs->ns_dev_subgroups = kzalloc(devgrp_size, GFP_KERNEL);
+ if (unlikely(!nilfs->ns_dev_subgroups)) {
+ err = -ENOMEM;
+- nilfs_msg(sb, KERN_ERR,
+- "unable to allocate memory for device group");
++ nilfs_err(sb, "unable to allocate memory for device group");
+ goto failed_create_device_group;
+ }
+
+@@ -1098,15 +1097,13 @@ int __init nilfs_sysfs_init(void)
+ nilfs_kset = kset_create_and_add(NILFS_ROOT_GROUP_NAME, NULL, fs_kobj);
+ if (!nilfs_kset) {
+ err = -ENOMEM;
+- nilfs_msg(NULL, KERN_ERR,
+- "unable to create sysfs entry: err=%d", err);
++ nilfs_err(NULL, "unable to create sysfs entry: err=%d", err);
+ goto failed_sysfs_init;
+ }
+
+ err = sysfs_create_group(&nilfs_kset->kobj, &nilfs_feature_attr_group);
+ if (unlikely(err)) {
+- nilfs_msg(NULL, KERN_ERR,
+- "unable to create feature group: err=%d", err);
++ nilfs_err(NULL, "unable to create feature group: err=%d", err);
+ goto cleanup_sysfs_init;
+ }
+
+diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
+index c8d869bc25b0c..0480034644aa7 100644
+--- a/fs/nilfs2/the_nilfs.c
++++ b/fs/nilfs2/the_nilfs.c
+@@ -183,7 +183,7 @@ static int nilfs_store_log_cursor(struct the_nilfs *nilfs,
+ nilfs_get_segnum_of_block(nilfs, nilfs->ns_last_pseg);
+ nilfs->ns_cno = nilfs->ns_last_cno + 1;
+ if (nilfs->ns_segnum >= nilfs->ns_nsegments) {
+- nilfs_msg(nilfs->ns_sb, KERN_ERR,
++ nilfs_err(nilfs->ns_sb,
+ "pointed segment number is out of range: segnum=%llu, nsegments=%lu",
+ (unsigned long long)nilfs->ns_segnum,
+ nilfs->ns_nsegments);
+@@ -210,12 +210,12 @@ int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
+ int err;
+
+ if (!valid_fs) {
+- nilfs_msg(sb, KERN_WARNING, "mounting unchecked fs");
++ nilfs_warn(sb, "mounting unchecked fs");
+ if (s_flags & SB_RDONLY) {
+- nilfs_msg(sb, KERN_INFO,
+- "recovery required for readonly filesystem");
+- nilfs_msg(sb, KERN_INFO,
+- "write access will be enabled during recovery");
++ nilfs_info(sb,
++ "recovery required for readonly filesystem");
++ nilfs_info(sb,
++ "write access will be enabled during recovery");
+ }
+ }
+
+@@ -230,12 +230,11 @@ int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
+ goto scan_error;
+
+ if (!nilfs_valid_sb(sbp[1])) {
+- nilfs_msg(sb, KERN_WARNING,
+- "unable to fall back to spare super block");
++ nilfs_warn(sb,
++ "unable to fall back to spare super block");
+ goto scan_error;
+ }
+- nilfs_msg(sb, KERN_INFO,
+- "trying rollback from an earlier position");
++ nilfs_info(sb, "trying rollback from an earlier position");
+
+ /*
+ * restore super block with its spare and reconfigure
+@@ -248,9 +247,9 @@ int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
+ /* verify consistency between two super blocks */
+ blocksize = BLOCK_SIZE << le32_to_cpu(sbp[0]->s_log_block_size);
+ if (blocksize != nilfs->ns_blocksize) {
+- nilfs_msg(sb, KERN_WARNING,
+- "blocksize differs between two super blocks (%d != %d)",
+- blocksize, nilfs->ns_blocksize);
++ nilfs_warn(sb,
++ "blocksize differs between two super blocks (%d != %d)",
++ blocksize, nilfs->ns_blocksize);
+ goto scan_error;
+ }
+
+@@ -269,8 +268,7 @@ int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
+
+ err = nilfs_load_super_root(nilfs, sb, ri.ri_super_root);
+ if (unlikely(err)) {
+- nilfs_msg(sb, KERN_ERR, "error %d while loading super root",
+- err);
++ nilfs_err(sb, "error %d while loading super root", err);
+ goto failed;
+ }
+
+@@ -285,28 +283,28 @@ int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
+ __u64 features;
+
+ if (nilfs_test_opt(nilfs, NORECOVERY)) {
+- nilfs_msg(sb, KERN_INFO,
+- "norecovery option specified, skipping roll-forward recovery");
++ nilfs_info(sb,
++ "norecovery option specified, skipping roll-forward recovery");
+ goto skip_recovery;
+ }
+ features = le64_to_cpu(nilfs->ns_sbp[0]->s_feature_compat_ro) &
+ ~NILFS_FEATURE_COMPAT_RO_SUPP;
+ if (features) {
+- nilfs_msg(sb, KERN_ERR,
++ nilfs_err(sb,
+ "couldn't proceed with recovery because of unsupported optional features (%llx)",
+ (unsigned long long)features);
+ err = -EROFS;
+ goto failed_unload;
+ }
+ if (really_read_only) {
+- nilfs_msg(sb, KERN_ERR,
++ nilfs_err(sb,
+ "write access unavailable, cannot proceed");
+ err = -EROFS;
+ goto failed_unload;
+ }
+ sb->s_flags &= ~SB_RDONLY;
+ } else if (nilfs_test_opt(nilfs, NORECOVERY)) {
+- nilfs_msg(sb, KERN_ERR,
++ nilfs_err(sb,
+ "recovery cancelled because norecovery option was specified for a read/write mount");
+ err = -EINVAL;
+ goto failed_unload;
+@@ -322,12 +320,12 @@ int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
+ up_write(&nilfs->ns_sem);
+
+ if (err) {
+- nilfs_msg(sb, KERN_ERR,
++ nilfs_err(sb,
+ "error %d updating super block. recovery unfinished.",
+ err);
+ goto failed_unload;
+ }
+- nilfs_msg(sb, KERN_INFO, "recovery complete");
++ nilfs_info(sb, "recovery complete");
+
+ skip_recovery:
+ nilfs_clear_recovery_info(&ri);
+@@ -335,7 +333,7 @@ int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
+ return 0;
+
+ scan_error:
+- nilfs_msg(sb, KERN_ERR, "error %d while searching super root", err);
++ nilfs_err(sb, "error %d while searching super root", err);
+ goto failed;
+
+ failed_unload:
+@@ -399,7 +397,7 @@ static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
+ u64 nsegments, nblocks;
+
+ if (le32_to_cpu(sbp->s_rev_level) < NILFS_MIN_SUPP_REV) {
+- nilfs_msg(nilfs->ns_sb, KERN_ERR,
++ nilfs_err(nilfs->ns_sb,
+ "unsupported revision (superblock rev.=%d.%d, current rev.=%d.%d). Please check the version of mkfs.nilfs(2).",
+ le32_to_cpu(sbp->s_rev_level),
+ le16_to_cpu(sbp->s_minor_rev_level),
+@@ -412,13 +410,11 @@ static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
+
+ nilfs->ns_inode_size = le16_to_cpu(sbp->s_inode_size);
+ if (nilfs->ns_inode_size > nilfs->ns_blocksize) {
+- nilfs_msg(nilfs->ns_sb, KERN_ERR,
+- "too large inode size: %d bytes",
++ nilfs_err(nilfs->ns_sb, "too large inode size: %d bytes",
+ nilfs->ns_inode_size);
+ return -EINVAL;
+ } else if (nilfs->ns_inode_size < NILFS_MIN_INODE_SIZE) {
+- nilfs_msg(nilfs->ns_sb, KERN_ERR,
+- "too small inode size: %d bytes",
++ nilfs_err(nilfs->ns_sb, "too small inode size: %d bytes",
+ nilfs->ns_inode_size);
+ return -EINVAL;
+ }
+@@ -427,8 +423,7 @@ static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
+
+ nilfs->ns_blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment);
+ if (nilfs->ns_blocks_per_segment < NILFS_SEG_MIN_BLOCKS) {
+- nilfs_msg(nilfs->ns_sb, KERN_ERR,
+- "too short segment: %lu blocks",
++ nilfs_err(nilfs->ns_sb, "too short segment: %lu blocks",
+ nilfs->ns_blocks_per_segment);
+ return -EINVAL;
+ }
+@@ -438,7 +433,7 @@ static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
+ le32_to_cpu(sbp->s_r_segments_percentage);
+ if (nilfs->ns_r_segments_percentage < 1 ||
+ nilfs->ns_r_segments_percentage > 99) {
+- nilfs_msg(nilfs->ns_sb, KERN_ERR,
++ nilfs_err(nilfs->ns_sb,
+ "invalid reserved segments percentage: %lu",
+ nilfs->ns_r_segments_percentage);
+ return -EINVAL;
+@@ -580,16 +575,16 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs,
+
+ if (!sbp[0]) {
+ if (!sbp[1]) {
+- nilfs_msg(sb, KERN_ERR, "unable to read superblock");
++ nilfs_err(sb, "unable to read superblock");
+ return -EIO;
+ }
+- nilfs_msg(sb, KERN_WARNING,
+- "unable to read primary superblock (blocksize = %d)",
+- blocksize);
++ nilfs_warn(sb,
++ "unable to read primary superblock (blocksize = %d)",
++ blocksize);
+ } else if (!sbp[1]) {
+- nilfs_msg(sb, KERN_WARNING,
+- "unable to read secondary superblock (blocksize = %d)",
+- blocksize);
++ nilfs_warn(sb,
++ "unable to read secondary superblock (blocksize = %d)",
++ blocksize);
+ }
+
+ /*
+@@ -611,14 +606,14 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs,
+ }
+ if (!valid[swp]) {
+ nilfs_release_super_block(nilfs);
+- nilfs_msg(sb, KERN_ERR, "couldn't find nilfs on the device");
++ nilfs_err(sb, "couldn't find nilfs on the device");
+ return -EINVAL;
+ }
+
+ if (!valid[!swp])
+- nilfs_msg(sb, KERN_WARNING,
+- "broken superblock, retrying with spare superblock (blocksize = %d)",
+- blocksize);
++ nilfs_warn(sb,
++ "broken superblock, retrying with spare superblock (blocksize = %d)",
++ blocksize);
+ if (swp)
+ nilfs_swap_super_block(nilfs);
+
+@@ -652,7 +647,7 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data)
+
+ blocksize = sb_min_blocksize(sb, NILFS_MIN_BLOCK_SIZE);
+ if (!blocksize) {
+- nilfs_msg(sb, KERN_ERR, "unable to set blocksize");
++ nilfs_err(sb, "unable to set blocksize");
+ err = -EINVAL;
+ goto out;
+ }
+@@ -671,7 +666,7 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data)
+ blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
+ if (blocksize < NILFS_MIN_BLOCK_SIZE ||
+ blocksize > NILFS_MAX_BLOCK_SIZE) {
+- nilfs_msg(sb, KERN_ERR,
++ nilfs_err(sb,
+ "couldn't mount because of unsupported filesystem blocksize %d",
+ blocksize);
+ err = -EINVAL;
+@@ -681,7 +676,7 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data)
+ int hw_blocksize = bdev_logical_block_size(sb->s_bdev);
+
+ if (blocksize < hw_blocksize) {
+- nilfs_msg(sb, KERN_ERR,
++ nilfs_err(sb,
+ "blocksize %d too small for device (sector-size = %d)",
+ blocksize, hw_blocksize);
+ err = -EINVAL;
+--
+2.43.0
+
--- /dev/null
+From 8ee2e43b6cbe233d3e9d5b32b48198a812cf13f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 Feb 2024 11:40:23 +0000
+Subject: nvmem: meson-efuse: fix function pointer type mismatch
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+[ Upstream commit cbd38332c140829ab752ba4e727f98be5c257f18 ]
+
+clang-16 warns about casting functions to incompatible types, as is done
+here to call clk_disable_unprepare:
+
+drivers/nvmem/meson-efuse.c:78:12: error: cast from 'void (*)(struct clk *)' to 'void (*)(void *)' converts to incompatible function type [-Werror,-Wcast-function-type-strict]
+ 78 | (void(*)(void *))clk_disable_unprepare,
+
+The pattern of getting, enabling and setting a disable callback for a
+clock can be replaced with devm_clk_get_enabled(), which also fixes
+this warning.
+
+Fixes: 611fbca1c861 ("nvmem: meson-efuse: add peripheral clock")
+Cc: Stable@vger.kernel.org
+Reported-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Justin Stitt <justinstitt@google.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114023.85535-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvmem/meson-efuse.c | 25 +++----------------------
+ 1 file changed, 3 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/nvmem/meson-efuse.c b/drivers/nvmem/meson-efuse.c
+index d6b533497ce1a..ba2714bef8d0e 100644
+--- a/drivers/nvmem/meson-efuse.c
++++ b/drivers/nvmem/meson-efuse.c
+@@ -47,7 +47,6 @@ static int meson_efuse_probe(struct platform_device *pdev)
+ struct nvmem_config *econfig;
+ struct clk *clk;
+ unsigned int size;
+- int ret;
+
+ sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0);
+ if (!sm_np) {
+@@ -60,27 +59,9 @@ static int meson_efuse_probe(struct platform_device *pdev)
+ if (!fw)
+ return -EPROBE_DEFER;
+
+- clk = devm_clk_get(dev, NULL);
+- if (IS_ERR(clk)) {
+- ret = PTR_ERR(clk);
+- if (ret != -EPROBE_DEFER)
+- dev_err(dev, "failed to get efuse gate");
+- return ret;
+- }
+-
+- ret = clk_prepare_enable(clk);
+- if (ret) {
+- dev_err(dev, "failed to enable gate");
+- return ret;
+- }
+-
+- ret = devm_add_action_or_reset(dev,
+- (void(*)(void *))clk_disable_unprepare,
+- clk);
+- if (ret) {
+- dev_err(dev, "failed to add disable callback");
+- return ret;
+- }
++ clk = devm_clk_get_enabled(dev, NULL);
++ if (IS_ERR(clk))
++ return dev_err_probe(dev, PTR_ERR(clk), "failed to get efuse gate");
+
+ if (meson_sm_call(fw, SM_EFUSE_USER_MAX, &size, 0, 0, 0, 0, 0) < 0) {
+ dev_err(dev, "failed to get max user");
+--
+2.43.0
+
--- /dev/null
+From 2c1119eb82ffed6d94489a4c80e4b776615fb2f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 29 Sep 2019 21:00:42 +0200
+Subject: parisc: Do not hardcode registers in checksum functions
+
+From: Helge Deller <deller@gmx.de>
+
+[ Upstream commit 52b2d91752a82d9350981eb3b3ffc4b325c84ba9 ]
+
+Do not hardcode processor registers r19 to r22 as scratch registers.
+Instead let the compiler decide, which may give better optimization
+results when the functions get inlined.
+
+Signed-off-by: Helge Deller <deller@gmx.de>
+Stable-dep-of: a2abae8f0b63 ("parisc: Fix ip_fast_csum")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/parisc/include/asm/checksum.h | 101 +++++++++++++++--------------
+ 1 file changed, 52 insertions(+), 49 deletions(-)
+
+diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h
+index 3cbf1f1c1188e..c1c22819a04d1 100644
+--- a/arch/parisc/include/asm/checksum.h
++++ b/arch/parisc/include/asm/checksum.h
+@@ -42,31 +42,32 @@ extern __wsum csum_partial_copy_from_user(const void __user *src,
+ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+ {
+ unsigned int sum;
++ unsigned long t0, t1, t2;
+
+ __asm__ __volatile__ (
+ " ldws,ma 4(%1), %0\n"
+ " addib,<= -4, %2, 2f\n"
+ "\n"
+-" ldws 4(%1), %%r20\n"
+-" ldws 8(%1), %%r21\n"
+-" add %0, %%r20, %0\n"
+-" ldws,ma 12(%1), %%r19\n"
+-" addc %0, %%r21, %0\n"
+-" addc %0, %%r19, %0\n"
+-"1: ldws,ma 4(%1), %%r19\n"
++" ldws 4(%1), %4\n"
++" ldws 8(%1), %5\n"
++" add %0, %4, %0\n"
++" ldws,ma 12(%1), %3\n"
++" addc %0, %5, %0\n"
++" addc %0, %3, %0\n"
++"1: ldws,ma 4(%1), %3\n"
+ " addib,< 0, %2, 1b\n"
+-" addc %0, %%r19, %0\n"
++" addc %0, %3, %0\n"
+ "\n"
+-" extru %0, 31, 16, %%r20\n"
+-" extru %0, 15, 16, %%r21\n"
+-" addc %%r20, %%r21, %0\n"
+-" extru %0, 15, 16, %%r21\n"
+-" add %0, %%r21, %0\n"
++" extru %0, 31, 16, %4\n"
++" extru %0, 15, 16, %5\n"
++" addc %4, %5, %0\n"
++" extru %0, 15, 16, %5\n"
++" add %0, %5, %0\n"
+ " subi -1, %0, %0\n"
+ "2:\n"
+- : "=r" (sum), "=r" (iph), "=r" (ihl)
++ : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (t0), "=r" (t1), "=r" (t2)
+ : "1" (iph), "2" (ihl)
+- : "r19", "r20", "r21", "memory");
++ : "memory");
+
+ return (__force __sum16)sum;
+ }
+@@ -126,6 +127,10 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+ __u32 len, __u8 proto,
+ __wsum sum)
+ {
++ unsigned long t0, t1, t2, t3;
++
++ len += proto; /* add 16-bit proto + len */
++
+ __asm__ __volatile__ (
+
+ #if BITS_PER_LONG > 32
+@@ -136,20 +141,19 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+ ** Try to keep 4 registers with "live" values ahead of the ALU.
+ */
+
+-" ldd,ma 8(%1), %%r19\n" /* get 1st saddr word */
+-" ldd,ma 8(%2), %%r20\n" /* get 1st daddr word */
+-" add %8, %3, %3\n"/* add 16-bit proto + len */
+-" add %%r19, %0, %0\n"
+-" ldd,ma 8(%1), %%r21\n" /* 2cd saddr */
+-" ldd,ma 8(%2), %%r22\n" /* 2cd daddr */
+-" add,dc %%r20, %0, %0\n"
+-" add,dc %%r21, %0, %0\n"
+-" add,dc %%r22, %0, %0\n"
++" ldd,ma 8(%1), %4\n" /* get 1st saddr word */
++" ldd,ma 8(%2), %5\n" /* get 1st daddr word */
++" add %4, %0, %0\n"
++" ldd,ma 8(%1), %6\n" /* 2nd saddr */
++" ldd,ma 8(%2), %7\n" /* 2nd daddr */
++" add,dc %5, %0, %0\n"
++" add,dc %6, %0, %0\n"
++" add,dc %7, %0, %0\n"
+ " add,dc %3, %0, %0\n" /* fold in proto+len | carry bit */
+-" extrd,u %0, 31, 32, %%r19\n" /* copy upper half down */
+-" depdi 0, 31, 32, %0\n" /* clear upper half */
+-" add %%r19, %0, %0\n" /* fold into 32-bits */
+-" addc 0, %0, %0\n" /* add carry */
++" extrd,u %0, 31, 32, %4\n"/* copy upper half down */
++" depdi 0, 31, 32, %0\n"/* clear upper half */
++" add %4, %0, %0\n" /* fold into 32-bits */
++" addc 0, %0, %0\n" /* add carry */
+
+ #else
+
+@@ -158,30 +162,29 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+ ** Insn stream is serialized on the carry bit here too.
+ ** result from the previous operation (eg r0 + x)
+ */
+-
+-" ldw,ma 4(%1), %%r19\n" /* get 1st saddr word */
+-" ldw,ma 4(%2), %%r20\n" /* get 1st daddr word */
+-" add %8, %3, %3\n" /* add 16-bit proto + len */
+-" add %%r19, %0, %0\n"
+-" ldw,ma 4(%1), %%r21\n" /* 2cd saddr */
+-" addc %%r20, %0, %0\n"
+-" ldw,ma 4(%2), %%r22\n" /* 2cd daddr */
+-" addc %%r21, %0, %0\n"
+-" ldw,ma 4(%1), %%r19\n" /* 3rd saddr */
+-" addc %%r22, %0, %0\n"
+-" ldw,ma 4(%2), %%r20\n" /* 3rd daddr */
+-" addc %%r19, %0, %0\n"
+-" ldw,ma 4(%1), %%r21\n" /* 4th saddr */
+-" addc %%r20, %0, %0\n"
+-" ldw,ma 4(%2), %%r22\n" /* 4th daddr */
+-" addc %%r21, %0, %0\n"
+-" addc %%r22, %0, %0\n"
++" ldw,ma 4(%1), %4\n" /* get 1st saddr word */
++" ldw,ma 4(%2), %5\n" /* get 1st daddr word */
++" add %4, %0, %0\n"
++" ldw,ma 4(%1), %6\n" /* 2nd saddr */
++" addc %5, %0, %0\n"
++" ldw,ma 4(%2), %7\n" /* 2nd daddr */
++" addc %6, %0, %0\n"
++" ldw,ma 4(%1), %4\n" /* 3rd saddr */
++" addc %7, %0, %0\n"
++" ldw,ma 4(%2), %5\n" /* 3rd daddr */
++" addc %4, %0, %0\n"
++" ldw,ma 4(%1), %6\n" /* 4th saddr */
++" addc %5, %0, %0\n"
++" ldw,ma 4(%2), %7\n" /* 4th daddr */
++" addc %6, %0, %0\n"
++" addc %7, %0, %0\n"
+ " addc %3, %0, %0\n" /* fold in proto+len, catch carry */
+
+ #endif
+- : "=r" (sum), "=r" (saddr), "=r" (daddr), "=r" (len)
+- : "0" (sum), "1" (saddr), "2" (daddr), "3" (len), "r" (proto)
+- : "r19", "r20", "r21", "r22", "memory");
++ : "=r" (sum), "=r" (saddr), "=r" (daddr), "=r" (len),
++ "=r" (t0), "=r" (t1), "=r" (t2), "=r" (t3)
++ : "0" (sum), "1" (saddr), "2" (daddr), "3" (len)
++ : "memory");
+ return csum_fold(sum);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From a7b8b9bafd54330c4b0e62fd81531609ccd8e9a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Feb 2024 11:15:56 -0800
+Subject: parisc: Fix csum_ipv6_magic on 32-bit systems
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 4408ba75e4ba80c91fde7e10bccccf388f5c09be ]
+
+Calculating the IPv6 checksum on 32-bit systems missed overflows when
+adding the proto+len fields into the checksum. This results in the
+following unit test failure.
+
+ # test_csum_ipv6_magic: ASSERTION FAILED at lib/checksum_kunit.c:506
+ Expected ( u64)csum_result == ( u64)expected, but
+ ( u64)csum_result == 46722 (0xb682)
+ ( u64)expected == 46721 (0xb681)
+ not ok 5 test_csum_ipv6_magic
+
+This is probably rarely seen in the real world because proto+len are
+usually small values which will rarely result in overflows when calculating
+the checksum. However, the unit test code uses large values for the length
+field, causing the test to fail.
+
+Fix the problem by adding the missing carry into the final checksum.
+
+Cc: Palmer Dabbelt <palmer@rivosinc.com>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Tested-by: Charlie Jenkins <charlie@rivosinc.com>
+Reviewed-by: Charlie Jenkins <charlie@rivosinc.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/parisc/include/asm/checksum.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h
+index 7efcd901b9656..0a02639514505 100644
+--- a/arch/parisc/include/asm/checksum.h
++++ b/arch/parisc/include/asm/checksum.h
+@@ -178,7 +178,8 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+ " ldw,ma 4(%2), %7\n" /* 4th daddr */
+ " addc %6, %0, %0\n"
+ " addc %7, %0, %0\n"
+-" addc %3, %0, %0\n" /* fold in proto+len, catch carry */
++" addc %3, %0, %0\n" /* fold in proto+len */
++" addc 0, %0, %0\n" /* add carry */
+
+ #endif
+ : "=r" (sum), "=r" (saddr), "=r" (daddr), "=r" (len),
+--
+2.43.0
+
--- /dev/null
+From 14d25bfed6981c007d368d36574d5646e7dcd989 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Feb 2024 15:46:31 -0800
+Subject: parisc: Fix csum_ipv6_magic on 64-bit systems
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 4b75b12d70506e31fc02356bbca60f8d5ca012d0 ]
+
+hppa 64-bit systems calculates the IPv6 checksum using 64-bit add
+operations. The last add folds protocol and length fields into the 64-bit
+result. While unlikely, this operation can overflow. The overflow can be
+triggered with a code sequence such as the following.
+
+ /* try to trigger massive overflows */
+ memset(tmp_buf, 0xff, sizeof(struct in6_addr));
+ csum_result = csum_ipv6_magic((struct in6_addr *)tmp_buf,
+ (struct in6_addr *)tmp_buf,
+ 0xffff, 0xff, 0xffffffff);
+
+Fix the problem by adding any overflows from the final add operation into
+the calculated checksum. Fortunately, we can do this without additional
+cost by replacing the add operation used to fold the checksum into 32 bit
+with "add,dc" to add in the missing carry.
+
+Cc: Palmer Dabbelt <palmer@rivosinc.com>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Charlie Jenkins <charlie@rivosinc.com>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/parisc/include/asm/checksum.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h
+index 0a02639514505..7861d365ba1e2 100644
+--- a/arch/parisc/include/asm/checksum.h
++++ b/arch/parisc/include/asm/checksum.h
+@@ -152,8 +152,8 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+ " add,dc %3, %0, %0\n" /* fold in proto+len | carry bit */
+ " extrd,u %0, 31, 32, %4\n"/* copy upper half down */
+ " depdi 0, 31, 32, %0\n"/* clear upper half */
+-" add %4, %0, %0\n" /* fold into 32-bits */
+-" addc 0, %0, %0\n" /* add carry */
++" add,dc %4, %0, %0\n" /* fold into 32-bits, plus carry */
++" addc 0, %0, %0\n" /* add final carry */
+
+ #else
+
+--
+2.43.0
+
--- /dev/null
+From 050a4dfc2ed005a701be7d175bc394559633debe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Feb 2024 09:55:26 -0800
+Subject: parisc: Fix ip_fast_csum
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit a2abae8f0b638c31bb9799d9dd847306e0d005bd ]
+
+IP checksum unit tests report the following error when run on hppa/hppa64.
+
+ # test_ip_fast_csum: ASSERTION FAILED at lib/checksum_kunit.c:463
+ Expected ( u64)csum_result == ( u64)expected, but
+ ( u64)csum_result == 33754 (0x83da)
+ ( u64)expected == 10946 (0x2ac2)
+ not ok 4 test_ip_fast_csum
+
+0x83da is the expected result if the IP header length is 20 bytes. 0x2ac2
+is the expected result if the IP header length is 24 bytes. The test fails
+with an IP header length of 24 bytes. It appears that ip_fast_csum()
+always returns the checksum for a 20-byte header, no matter how long
+the header actually is.
+
+Code analysis shows a suspicious assembler sequence in ip_fast_csum().
+
+ " addc %0, %3, %0\n"
+ "1: ldws,ma 4(%1), %3\n"
+ " addib,< 0, %2, 1b\n" <---
+
+While my understanding of HPPA assembler is limited, it does not seem
+to make much sense to subtract 0 from a register and to expect the result
+to ever be negative. Subtracting 1 from the length parameter makes more
+sense. On top of that, the operation should be repeated if and only if
+the result is still > 0, so change the suspicious instruction to
+ " addib,> -1, %2, 1b\n"
+
+The IP checksum unit test passes after this change.
+
+Cc: Palmer Dabbelt <palmer@rivosinc.com>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Tested-by: Charlie Jenkins <charlie@rivosinc.com>
+Reviewed-by: Charlie Jenkins <charlie@rivosinc.com>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/parisc/include/asm/checksum.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h
+index c1c22819a04d1..7efcd901b9656 100644
+--- a/arch/parisc/include/asm/checksum.h
++++ b/arch/parisc/include/asm/checksum.h
+@@ -55,7 +55,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+ " addc %0, %5, %0\n"
+ " addc %0, %3, %0\n"
+ "1: ldws,ma 4(%1), %3\n"
+-" addib,< 0, %2, 1b\n"
++" addib,> -1, %2, 1b\n"
+ " addc %0, %3, %0\n"
+ "\n"
+ " extru %0, 31, 16, %4\n"
+--
+2.43.0
+
--- /dev/null
+From 9f97fcdfbca270cade377b9fa50a81ef923ddbb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Feb 2024 12:33:51 -0800
+Subject: parisc: Strip upper 32 bit of sum in csum_ipv6_magic for 64-bit
+ builds
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 0568b6f0d863643db2edcc7be31165740c89fa82 ]
+
+IPv6 checksum tests with unaligned addresses on 64-bit builds result
+in unexpected failures.
+
+Expected expected == csum_result, but
+ expected == 46591 (0xb5ff)
+ csum_result == 46381 (0xb52d)
+with alignment offset 1
+
+Oddly enough, the problem disappeared after adding test code into
+the beginning of csum_ipv6_magic().
+
+As it turns out, the 'sum' parameter of csum_ipv6_magic() is declared as
+__wsum, which is a 32-bit variable. However, it is treated as 64-bit
+variable in the 64-bit assembler code. Tests showed that the upper 32 bit
+of the register used to pass the variable are _not_ cleared when entering
+the function. This can result in checksum calculation errors.
+
+Clearing the upper 32 bit of 'sum' as first operation in the assembler
+code fixes the problem.
+
+Acked-by: Helge Deller <deller@gmx.de>
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/parisc/include/asm/checksum.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h
+index 7861d365ba1e2..ef34e8f839d55 100644
+--- a/arch/parisc/include/asm/checksum.h
++++ b/arch/parisc/include/asm/checksum.h
+@@ -141,6 +141,7 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+ ** Try to keep 4 registers with "live" values ahead of the ALU.
+ */
+
++" depdi 0, 31, 32, %0\n"/* clear upper half of incoming checksum */
+ " ldd,ma 8(%1), %4\n" /* get 1st saddr word */
+ " ldd,ma 8(%2), %5\n" /* get 1st daddr word */
+ " add %4, %0, %0\n"
+--
+2.43.0
+
--- /dev/null
+From 5ecd6ea79d068313aacbc6465cfe1be3d59540e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Oct 2021 14:59:25 +0200
+Subject: PCI: Drop pci_device_remove() test of pci_dev->driver
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 097d9d414433315122f759ee6c2d8a7417a8ff0f ]
+
+When the driver core calls pci_device_remove(), there is a driver bound
+to the device, so pci_dev->driver is never NULL.
+
+Remove the unnecessary test of pci_dev->driver.
+
+Link: https://lore.kernel.org/r/20211004125935.2300113-2-u.kleine-koenig@pengutronix.de
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Stable-dep-of: 9d5286d4e7f6 ("PCI/PM: Drain runtime-idle callbacks before driver removal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci-driver.c | 16 +++++++---------
+ 1 file changed, 7 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
+index 70c8584b3ffcc..7644a282bfdb8 100644
+--- a/drivers/pci/pci-driver.c
++++ b/drivers/pci/pci-driver.c
+@@ -439,16 +439,14 @@ static int pci_device_remove(struct device *dev)
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct pci_driver *drv = pci_dev->driver;
+
+- if (drv) {
+- if (drv->remove) {
+- pm_runtime_get_sync(dev);
+- drv->remove(pci_dev);
+- pm_runtime_put_noidle(dev);
+- }
+- pcibios_free_irq(pci_dev);
+- pci_dev->driver = NULL;
+- pci_iov_remove(pci_dev);
++ if (drv->remove) {
++ pm_runtime_get_sync(dev);
++ drv->remove(pci_dev);
++ pm_runtime_put_noidle(dev);
+ }
++ pcibios_free_irq(pci_dev);
++ pci_dev->driver = NULL;
++ pci_iov_remove(pci_dev);
+
+ /* Undo the runtime PM settings in local_pci_probe() */
+ pm_runtime_put_sync(dev);
+--
+2.43.0
+
--- /dev/null
+From afe96e755f1efe5384755121c4133672853933a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 11:45:38 +0100
+Subject: PCI/PM: Drain runtime-idle callbacks before driver removal
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 9d5286d4e7f68beab450deddbb6a32edd5ecf4bf ]
+
+A race condition between the .runtime_idle() callback and the .remove()
+callback in the rtsx_pcr PCI driver leads to a kernel crash due to an
+unhandled page fault [1].
+
+The problem is that rtsx_pci_runtime_idle() is not expected to be running
+after pm_runtime_get_sync() has been called, but the latter doesn't really
+guarantee that. It only guarantees that the suspend and resume callbacks
+will not be running when it returns.
+
+However, if a .runtime_idle() callback is already running when
+pm_runtime_get_sync() is called, the latter will notice that the runtime PM
+status of the device is RPM_ACTIVE and it will return right away without
+waiting for the former to complete. In fact, it cannot wait for
+.runtime_idle() to complete because it may be called from that callback (it
+arguably does not make much sense to do that, but it is not strictly
+prohibited).
+
+Thus in general, whoever is providing a .runtime_idle() callback needs
+to protect it from running in parallel with whatever code runs after
+pm_runtime_get_sync(). [Note that .runtime_idle() will not start after
+pm_runtime_get_sync() has returned, but it may continue running then if it
+has started earlier.]
+
+One way to address that race condition is to call pm_runtime_barrier()
+after pm_runtime_get_sync() (not before it, because a nonzero value of the
+runtime PM usage counter is necessary to prevent runtime PM callbacks from
+being invoked) to wait for the .runtime_idle() callback to complete should
+it be running at that point. A suitable place for doing that is in
+pci_device_remove() which calls pm_runtime_get_sync() before removing the
+driver, so it may as well call pm_runtime_barrier() subsequently, which
+will prevent the race in question from occurring, not just in the rtsx_pcr
+driver, but in any PCI drivers providing .runtime_idle() callbacks.
+
+Link: https://lore.kernel.org/lkml/20240229062201.49500-1-kai.heng.feng@canonical.com/ # [1]
+Link: https://lore.kernel.org/r/5761426.DvuYhMxLoT@kreacher
+Reported-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Ricky Wu <ricky_wu@realtek.com>
+Acked-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci-driver.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
+index 7644a282bfdb8..617b13c94b390 100644
+--- a/drivers/pci/pci-driver.c
++++ b/drivers/pci/pci-driver.c
+@@ -441,6 +441,13 @@ static int pci_device_remove(struct device *dev)
+
+ if (drv->remove) {
+ pm_runtime_get_sync(dev);
++ /*
++ * If the driver provides a .runtime_idle() callback and it has
++ * started to run already, it may continue to run in parallel
++ * with the code below, so wait until all of the runtime PM
++ * activity has completed.
++ */
++ pm_runtime_barrier(dev);
+ drv->remove(pci_dev);
+ pm_runtime_put_noidle(dev);
+ }
+--
+2.43.0
+
--- /dev/null
+From 1d213ef8f90c8bf0e35990f26001d4af1a4d01b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Mar 2024 17:26:57 +0800
+Subject: PM: sleep: wakeirq: fix wake irq warning in system suspend
+
+From: Qingliang Li <qingliang.li@mediatek.com>
+
+[ Upstream commit e7a7681c859643f3f2476b2a28a494877fd89442 ]
+
+When driver uses pm_runtime_force_suspend() as the system suspend callback
+function and registers the wake irq with reverse enable ordering, the wake
+irq will be re-enabled when entering system suspend, triggering an
+'Unbalanced enable for IRQ xxx' warning. In this scenario, the call
+sequence during system suspend is as follows:
+ suspend_devices_and_enter()
+ -> dpm_suspend_start()
+ -> dpm_run_callback()
+ -> pm_runtime_force_suspend()
+ -> dev_pm_enable_wake_irq_check()
+ -> dev_pm_enable_wake_irq_complete()
+
+ -> suspend_enter()
+ -> dpm_suspend_noirq()
+ -> device_wakeup_arm_wake_irqs()
+ -> dev_pm_arm_wake_irq()
+
+To fix this issue, complete the setting of WAKE_IRQ_DEDICATED_ENABLED flag
+in dev_pm_enable_wake_irq_complete() to avoid redundant irq enablement.
+
+Fixes: 8527beb12087 ("PM: sleep: wakeirq: fix wake irq arming")
+Reviewed-by: Dhruva Gole <d-gole@ti.com>
+Signed-off-by: Qingliang Li <qingliang.li@mediatek.com>
+Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
+Cc: 5.16+ <stable@vger.kernel.org> # 5.16+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/power/wakeirq.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c
+index 46654adf00a10..20b07fa2792ba 100644
+--- a/drivers/base/power/wakeirq.c
++++ b/drivers/base/power/wakeirq.c
+@@ -365,8 +365,10 @@ void dev_pm_enable_wake_irq_complete(struct device *dev)
+ return;
+
+ if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED &&
+- wirq->status & WAKE_IRQ_DEDICATED_REVERSE)
++ wirq->status & WAKE_IRQ_DEDICATED_REVERSE) {
+ enable_irq(wirq->irq);
++ wirq->status |= WAKE_IRQ_DEDICATED_ENABLED;
++ }
+ }
+
+ /**
+--
+2.43.0
+
--- /dev/null
+From 48969729d4e23b856564e7c8e434cdcce1575d3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 12:14:59 +0530
+Subject: PM: suspend: Set mem_sleep_current during kernel command line setup
+
+From: Maulik Shah <quic_mkshah@quicinc.com>
+
+[ Upstream commit 9bc4ffd32ef8943f5c5a42c9637cfd04771d021b ]
+
+psci_init_system_suspend() invokes suspend_set_ops() very early during
+bootup even before kernel command line for mem_sleep_default is setup.
+This leads to kernel command line mem_sleep_default=s2idle not working
+as mem_sleep_current gets changed to deep via suspend_set_ops() and never
+changes back to s2idle.
+
+Set mem_sleep_current along with mem_sleep_default during kernel command
+line setup as default suspend mode.
+
+Fixes: faf7ec4a92c0 ("drivers: firmware: psci: add system suspend support")
+CC: stable@vger.kernel.org # 5.4+
+Signed-off-by: Maulik Shah <quic_mkshah@quicinc.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/power/suspend.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
+index 5dea2778a3dbb..c6433d3c04a0e 100644
+--- a/kernel/power/suspend.c
++++ b/kernel/power/suspend.c
+@@ -187,6 +187,7 @@ static int __init mem_sleep_default_setup(char *str)
+ if (mem_sleep_labels[state] &&
+ !strcmp(str, mem_sleep_labels[state])) {
+ mem_sleep_default = state;
++ mem_sleep_current = state;
+ break;
+ }
+
+--
+2.43.0
+
--- /dev/null
+From c4c34fdff7c5346b072f068a60c7769dc75dd682 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 23:25:19 +1100
+Subject: powerpc/fsl: Fix mfpmr build errors with newer binutils
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit 5f491356b7149564ab22323ccce79c8d595bfd0c ]
+
+Binutils 2.38 complains about the use of mfpmr when building
+ppc6xx_defconfig:
+
+ CC arch/powerpc/kernel/pmc.o
+ {standard input}: Assembler messages:
+ {standard input}:45: Error: unrecognized opcode: `mfpmr'
+ {standard input}:56: Error: unrecognized opcode: `mtpmr'
+
+This is because by default the kernel is built with -mcpu=powerpc, and
+the mt/mfpmr instructions are not defined.
+
+It can be avoided by enabling CONFIG_E300C3_CPU, but just adding that to
+the defconfig will leave open the possibility of randconfig failures.
+
+So add machine directives around the mt/mfpmr instructions to tell
+binutils how to assemble them.
+
+Cc: stable@vger.kernel.org
+Reported-by: Jan-Benedict Glaw <jbglaw@lug-owl.de>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20240229122521.762431-3-mpe@ellerman.id.au
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/include/asm/reg_fsl_emb.h | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/arch/powerpc/include/asm/reg_fsl_emb.h b/arch/powerpc/include/asm/reg_fsl_emb.h
+index a21f529c43d96..8359c06d92d9f 100644
+--- a/arch/powerpc/include/asm/reg_fsl_emb.h
++++ b/arch/powerpc/include/asm/reg_fsl_emb.h
+@@ -12,9 +12,16 @@
+ #ifndef __ASSEMBLY__
+ /* Performance Monitor Registers */
+ #define mfpmr(rn) ({unsigned int rval; \
+- asm volatile("mfpmr %0," __stringify(rn) \
++ asm volatile(".machine push; " \
++ ".machine e300; " \
++ "mfpmr %0," __stringify(rn) ";" \
++ ".machine pop; " \
+ : "=r" (rval)); rval;})
+-#define mtpmr(rn, v) asm volatile("mtpmr " __stringify(rn) ",%0" : : "r" (v))
++#define mtpmr(rn, v) asm volatile(".machine push; " \
++ ".machine e300; " \
++ "mtpmr " __stringify(rn) ",%0; " \
++ ".machine pop; " \
++ : : "r" (v))
+ #endif /* __ASSEMBLY__ */
+
+ /* Freescale Book E Performance Monitor APU Registers */
+--
+2.43.0
+
--- /dev/null
+From 080d45a57be6a9ea8789b2615297a36ee59402d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Jan 2024 00:21:31 -0800
+Subject: Revert "Revert "md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d""
+
+From: Song Liu <song@kernel.org>
+
+[ Upstream commit 3445139e3a594be77eff48bc17eff67cf983daed ]
+
+This reverts commit bed9e27baf52a09b7ba2a3714f1e24e17ced386d.
+
+The original set [1][2] was expected to undo a suboptimal fix in [2], and
+replace it with a better fix [1]. However, as reported by Dan Moulding [2]
+causes an issue with raid5 with journal device.
+
+Revert [2] for now to close the issue. We will follow up on another issue
+reported by Juxiao Bi, as [2] is expected to fix it. We believe this is a
+good trade-off, because the latter issue happens less freqently.
+
+In the meanwhile, we will NOT revert [1], as it contains the right logic.
+
+[1] commit d6e035aad6c0 ("md: bypass block throttle for superblock update")
+[2] commit bed9e27baf52 ("Revert "md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d"")
+
+Reported-by: Dan Moulding <dan@danm.net>
+Closes: https://lore.kernel.org/linux-raid/20240123005700.9302-1-dan@danm.net/
+Fixes: bed9e27baf52 ("Revert "md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d"")
+Cc: stable@vger.kernel.org # v5.19+
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Yu Kuai <yukuai3@huawei.com>
+Signed-off-by: Song Liu <song@kernel.org>
+Reviewed-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20240125082131.788600-1-song@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid5.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
+index 0bea103f63d55..f3d60c4b34b8c 100644
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -36,6 +36,7 @@
+ */
+
+ #include <linux/blkdev.h>
++#include <linux/delay.h>
+ #include <linux/kthread.h>
+ #include <linux/raid/pq.h>
+ #include <linux/async_tx.h>
+@@ -6334,7 +6335,18 @@ static void raid5d(struct md_thread *thread)
+ spin_unlock_irq(&conf->device_lock);
+ md_check_recovery(mddev);
+ spin_lock_irq(&conf->device_lock);
++
++ /*
++ * Waiting on MD_SB_CHANGE_PENDING below may deadlock
++ * seeing md_check_recovery() is needed to clear
++ * the flag when using mdmon.
++ */
++ continue;
+ }
++
++ wait_event_lock_irq(mddev->sb_wait,
++ !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags),
++ conf->device_lock);
+ }
+ pr_debug("%d stripes handled\n", handled);
+
+--
+2.43.0
+
--- /dev/null
+From f86962b17c8a108cc4a462ea57b5f55b945e4ca9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Mar 2024 09:19:20 -0400
+Subject: ring-buffer: Fix full_waiters_pending in poll
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit 8145f1c35fa648da662078efab299c4467b85ad5 ]
+
+If a reader of the ring buffer is doing a poll, and waiting for the ring
+buffer to hit a specific watermark, there could be a case where it gets
+into an infinite ping-pong loop.
+
+The poll code has:
+
+ rbwork->full_waiters_pending = true;
+ if (!cpu_buffer->shortest_full ||
+ cpu_buffer->shortest_full > full)
+ cpu_buffer->shortest_full = full;
+
+The writer will see full_waiters_pending and check if the ring buffer is
+filled over the percentage of the shortest_full value. If it is, it calls
+an irq_work to wake up all the waiters.
+
+But the code could get into a circular loop:
+
+ CPU 0 CPU 1
+ ----- -----
+ [ Poll ]
+ [ shortest_full = 0 ]
+ rbwork->full_waiters_pending = true;
+ if (rbwork->full_waiters_pending &&
+ [ buffer percent ] > shortest_full) {
+ rbwork->wakeup_full = true;
+ [ queue_irqwork ]
+
+ cpu_buffer->shortest_full = full;
+
+ [ IRQ work ]
+ if (rbwork->wakeup_full) {
+ cpu_buffer->shortest_full = 0;
+ wakeup poll waiters;
+ [woken]
+ if ([ buffer percent ] > full)
+ break;
+ rbwork->full_waiters_pending = true;
+ if (rbwork->full_waiters_pending &&
+ [ buffer percent ] > shortest_full) {
+ rbwork->wakeup_full = true;
+ [ queue_irqwork ]
+
+ cpu_buffer->shortest_full = full;
+
+ [ IRQ work ]
+ if (rbwork->wakeup_full) {
+ cpu_buffer->shortest_full = 0;
+ wakeup poll waiters;
+ [woken]
+
+ [ Wash, rinse, repeat! ]
+
+In the poll, the shortest_full needs to be set before the
+full_pending_waiters, as once that is set, the writer will compare the
+current shortest_full (which is incorrect) to decide to call the irq_work,
+which will reset the shortest_full (expecting the readers to update it).
+
+Also move the setting of full_waiters_pending after the check if the ring
+buffer has the required percentage filled. There's no reason to tell the
+writer to wake up waiters if there are no waiters.
+
+Link: https://lore.kernel.org/linux-trace-kernel/20240312131952.630922155@goodmis.org
+
+Cc: stable@vger.kernel.org
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Fixes: 42fb0a1e84ff5 ("tracing/ring-buffer: Have polling block on watermark")
+Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/ring_buffer.c | 27 ++++++++++++++++++++-------
+ 1 file changed, 20 insertions(+), 7 deletions(-)
+
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index a9c90088af780..d2dba546fbbe1 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -761,16 +761,32 @@ __poll_t ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu,
+ poll_wait(filp, &rbwork->full_waiters, poll_table);
+
+ raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
+- rbwork->full_waiters_pending = true;
+ if (!cpu_buffer->shortest_full ||
+ cpu_buffer->shortest_full > full)
+ cpu_buffer->shortest_full = full;
+ raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
+- } else {
+- poll_wait(filp, &rbwork->waiters, poll_table);
+- rbwork->waiters_pending = true;
++ if (full_hit(buffer, cpu, full))
++ return EPOLLIN | EPOLLRDNORM;
++ /*
++ * Only allow full_waiters_pending update to be seen after
++ * the shortest_full is set. If the writer sees the
++ * full_waiters_pending flag set, it will compare the
++ * amount in the ring buffer to shortest_full. If the amount
++ * in the ring buffer is greater than the shortest_full
++ * percent, it will call the irq_work handler to wake up
++ * this list. The irq_handler will reset shortest_full
++ * back to zero. That's done under the reader_lock, but
++ * the below smp_mb() makes sure that the update to
++ * full_waiters_pending doesn't leak up into the above.
++ */
++ smp_mb();
++ rbwork->full_waiters_pending = true;
++ return 0;
+ }
+
++ poll_wait(filp, &rbwork->waiters, poll_table);
++ rbwork->waiters_pending = true;
++
+ /*
+ * There's a tight race between setting the waiters_pending and
+ * checking if the ring buffer is empty. Once the waiters_pending bit
+@@ -786,9 +802,6 @@ __poll_t ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu,
+ */
+ smp_mb();
+
+- if (full)
+- return full_hit(buffer, cpu, full) ? EPOLLIN | EPOLLRDNORM : 0;
+-
+ if ((cpu == RING_BUFFER_ALL_CPUS && !ring_buffer_empty(buffer)) ||
+ (cpu != RING_BUFFER_ALL_CPUS && !ring_buffer_empty_cpu(buffer, cpu)))
+ return EPOLLIN | EPOLLRDNORM;
+--
+2.43.0
+
--- /dev/null
+From 159f0b83e44933572f784ad80af38d0c39fee546 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Mar 2024 15:24:04 -0500
+Subject: ring-buffer: Fix resetting of shortest_full
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit 68282dd930ea38b068ce2c109d12405f40df3f93 ]
+
+The "shortest_full" variable is used to keep track of the waiter that is
+waiting for the smallest amount on the ring buffer before being woken up.
+When a tasks waits on the ring buffer, it passes in a "full" value that is
+a percentage. 0 means wake up on any data. 1-100 means wake up from 1% to
+100% full buffer.
+
+As all waiters are on the same wait queue, the wake up happens for the
+waiter with the smallest percentage.
+
+The problem is that the smallest_full on the cpu_buffer that stores the
+smallest amount doesn't get reset when all the waiters are woken up. It
+does get reset when the ring buffer is reset (echo > /sys/kernel/tracing/trace).
+
+This means that tasks may be woken up more often then when they want to
+be. Instead, have the shortest_full field get reset just before waking up
+all the tasks. If the tasks wait again, they will update the shortest_full
+before sleeping.
+
+Also add locking around setting of shortest_full in the poll logic, and
+change "work" to "rbwork" to match the variable name for rb_irq_work
+structures that are used in other places.
+
+Link: https://lore.kernel.org/linux-trace-kernel/20240308202431.948914369@goodmis.org
+
+Cc: stable@vger.kernel.org
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: linke li <lilinke99@qq.com>
+Cc: Rabin Vincent <rabin@rab.in>
+Fixes: 2c2b0a78b3739 ("ring-buffer: Add percentage of ring buffer full to wake up reader")
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Stable-dep-of: 8145f1c35fa6 ("ring-buffer: Fix full_waiters_pending in poll")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/ring_buffer.c | 30 +++++++++++++++++++++++-------
+ 1 file changed, 23 insertions(+), 7 deletions(-)
+
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index ed505c6de7cae..a9c90088af780 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -601,8 +601,19 @@ static void rb_wake_up_waiters(struct irq_work *work)
+
+ wake_up_all(&rbwork->waiters);
+ if (rbwork->full_waiters_pending || rbwork->wakeup_full) {
++ /* Only cpu_buffer sets the above flags */
++ struct ring_buffer_per_cpu *cpu_buffer =
++ container_of(rbwork, struct ring_buffer_per_cpu, irq_work);
++
++ /* Called from interrupt context */
++ raw_spin_lock(&cpu_buffer->reader_lock);
+ rbwork->wakeup_full = false;
+ rbwork->full_waiters_pending = false;
++
++ /* Waking up all waiters, they will reset the shortest full */
++ cpu_buffer->shortest_full = 0;
++ raw_spin_unlock(&cpu_buffer->reader_lock);
++
+ wake_up_all(&rbwork->full_waiters);
+ }
+ }
+@@ -731,28 +742,33 @@ __poll_t ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu,
+ struct file *filp, poll_table *poll_table, int full)
+ {
+ struct ring_buffer_per_cpu *cpu_buffer;
+- struct rb_irq_work *work;
++ struct rb_irq_work *rbwork;
+
+ if (cpu == RING_BUFFER_ALL_CPUS) {
+- work = &buffer->irq_work;
++ rbwork = &buffer->irq_work;
+ full = 0;
+ } else {
+ if (!cpumask_test_cpu(cpu, buffer->cpumask))
+ return EPOLLERR;
+
+ cpu_buffer = buffer->buffers[cpu];
+- work = &cpu_buffer->irq_work;
++ rbwork = &cpu_buffer->irq_work;
+ }
+
+ if (full) {
+- poll_wait(filp, &work->full_waiters, poll_table);
+- work->full_waiters_pending = true;
++ unsigned long flags;
++
++ poll_wait(filp, &rbwork->full_waiters, poll_table);
++
++ raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
++ rbwork->full_waiters_pending = true;
+ if (!cpu_buffer->shortest_full ||
+ cpu_buffer->shortest_full > full)
+ cpu_buffer->shortest_full = full;
++ raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
+ } else {
+- poll_wait(filp, &work->waiters, poll_table);
+- work->waiters_pending = true;
++ poll_wait(filp, &rbwork->waiters, poll_table);
++ rbwork->waiters_pending = true;
+ }
+
+ /*
+--
+2.43.0
+
--- /dev/null
+From cee319a8380ca8519cdb409461b3c353856b566d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Feb 2024 15:20:09 +0100
+Subject: s390/zcrypt: fix reference counting on zcrypt card objects
+
+From: Harald Freudenberger <freude@linux.ibm.com>
+
+[ Upstream commit 50ed48c80fecbe17218afed4f8bed005c802976c ]
+
+Tests with hot-plugging crytpo cards on KVM guests with debug
+kernel build revealed an use after free for the load field of
+the struct zcrypt_card. The reason was an incorrect reference
+handling of the zcrypt card object which could lead to a free
+of the zcrypt card object while it was still in use.
+
+This is an example of the slab message:
+
+ kernel: 0x00000000885a7512-0x00000000885a7513 @offset=1298. First byte 0x68 instead of 0x6b
+ kernel: Allocated in zcrypt_card_alloc+0x36/0x70 [zcrypt] age=18046 cpu=3 pid=43
+ kernel: kmalloc_trace+0x3f2/0x470
+ kernel: zcrypt_card_alloc+0x36/0x70 [zcrypt]
+ kernel: zcrypt_cex4_card_probe+0x26/0x380 [zcrypt_cex4]
+ kernel: ap_device_probe+0x15c/0x290
+ kernel: really_probe+0xd2/0x468
+ kernel: driver_probe_device+0x40/0xf0
+ kernel: __device_attach_driver+0xc0/0x140
+ kernel: bus_for_each_drv+0x8c/0xd0
+ kernel: __device_attach+0x114/0x198
+ kernel: bus_probe_device+0xb4/0xc8
+ kernel: device_add+0x4d2/0x6e0
+ kernel: ap_scan_adapter+0x3d0/0x7c0
+ kernel: ap_scan_bus+0x5a/0x3b0
+ kernel: ap_scan_bus_wq_callback+0x40/0x60
+ kernel: process_one_work+0x26e/0x620
+ kernel: worker_thread+0x21c/0x440
+ kernel: Freed in zcrypt_card_put+0x54/0x80 [zcrypt] age=9024 cpu=3 pid=43
+ kernel: kfree+0x37e/0x418
+ kernel: zcrypt_card_put+0x54/0x80 [zcrypt]
+ kernel: ap_device_remove+0x4c/0xe0
+ kernel: device_release_driver_internal+0x1c4/0x270
+ kernel: bus_remove_device+0x100/0x188
+ kernel: device_del+0x164/0x3c0
+ kernel: device_unregister+0x30/0x90
+ kernel: ap_scan_adapter+0xc8/0x7c0
+ kernel: ap_scan_bus+0x5a/0x3b0
+ kernel: ap_scan_bus_wq_callback+0x40/0x60
+ kernel: process_one_work+0x26e/0x620
+ kernel: worker_thread+0x21c/0x440
+ kernel: kthread+0x150/0x168
+ kernel: __ret_from_fork+0x3c/0x58
+ kernel: ret_from_fork+0xa/0x30
+ kernel: Slab 0x00000372022169c0 objects=20 used=18 fp=0x00000000885a7c88 flags=0x3ffff00000000a00(workingset|slab|node=0|zone=1|lastcpupid=0x1ffff)
+ kernel: Object 0x00000000885a74b8 @offset=1208 fp=0x00000000885a7c88
+ kernel: Redzone 00000000885a74b0: bb bb bb bb bb bb bb bb ........
+ kernel: Object 00000000885a74b8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
+ kernel: Object 00000000885a74c8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
+ kernel: Object 00000000885a74d8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
+ kernel: Object 00000000885a74e8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
+ kernel: Object 00000000885a74f8: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk
+ kernel: Object 00000000885a7508: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 68 4b 6b 6b 6b a5 kkkkkkkkkkhKkkk.
+ kernel: Redzone 00000000885a7518: bb bb bb bb bb bb bb bb ........
+ kernel: Padding 00000000885a756c: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZ
+ kernel: CPU: 0 PID: 387 Comm: systemd-udevd Not tainted 6.8.0-HF #2
+ kernel: Hardware name: IBM 3931 A01 704 (KVM/Linux)
+ kernel: Call Trace:
+ kernel: [<00000000ca5ab5b8>] dump_stack_lvl+0x90/0x120
+ kernel: [<00000000c99d78bc>] check_bytes_and_report+0x114/0x140
+ kernel: [<00000000c99d53cc>] check_object+0x334/0x3f8
+ kernel: [<00000000c99d820c>] alloc_debug_processing+0xc4/0x1f8
+ kernel: [<00000000c99d852e>] get_partial_node.part.0+0x1ee/0x3e0
+ kernel: [<00000000c99d94ec>] ___slab_alloc+0xaf4/0x13c8
+ kernel: [<00000000c99d9e38>] __slab_alloc.constprop.0+0x78/0xb8
+ kernel: [<00000000c99dc8dc>] __kmalloc+0x434/0x590
+ kernel: [<00000000c9b4c0ce>] ext4_htree_store_dirent+0x4e/0x1c0
+ kernel: [<00000000c9b908a2>] htree_dirblock_to_tree+0x17a/0x3f0
+ kernel: [<00000000c9b919dc>] ext4_htree_fill_tree+0x134/0x400
+ kernel: [<00000000c9b4b3d0>] ext4_dx_readdir+0x160/0x2f0
+ kernel: [<00000000c9b4bedc>] ext4_readdir+0x5f4/0x760
+ kernel: [<00000000c9a7efc4>] iterate_dir+0xb4/0x280
+ kernel: [<00000000c9a7f1ea>] __do_sys_getdents64+0x5a/0x120
+ kernel: [<00000000ca5d6946>] __do_syscall+0x256/0x310
+ kernel: [<00000000ca5eea10>] system_call+0x70/0x98
+ kernel: INFO: lockdep is turned off.
+ kernel: FIX kmalloc-96: Restoring Poison 0x00000000885a7512-0x00000000885a7513=0x6b
+ kernel: FIX kmalloc-96: Marking all objects used
+
+The fix is simple: Before use of the queue not only the queue object
+but also the card object needs to increase it's reference count
+with a call to zcrypt_card_get(). Similar after use of the queue
+not only the queue but also the card object's reference count is
+decreased with zcrypt_card_put().
+
+Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
+Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/crypto/zcrypt_api.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
+index f376dfcd7dbeb..69c1df560e2f1 100644
+--- a/drivers/s390/crypto/zcrypt_api.c
++++ b/drivers/s390/crypto/zcrypt_api.c
+@@ -574,6 +574,7 @@ static inline struct zcrypt_queue *zcrypt_pick_queue(struct zcrypt_card *zc,
+ {
+ if (!zq || !try_module_get(zq->queue->ap_dev.drv->driver.owner))
+ return NULL;
++ zcrypt_card_get(zc);
+ zcrypt_queue_get(zq);
+ get_device(&zq->queue->ap_dev.device);
+ atomic_add(weight, &zc->load);
+@@ -593,6 +594,7 @@ static inline void zcrypt_drop_queue(struct zcrypt_card *zc,
+ atomic_sub(weight, &zq->load);
+ put_device(&zq->queue->ap_dev.device);
+ zcrypt_queue_put(zq);
++ zcrypt_card_put(zc);
+ module_put(mod);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 1342ff7226d2b289e5f43c7619c2a8a25bcddaed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Feb 2024 16:08:02 -0800
+Subject: selftests/mqueue: Set timeout to 180 seconds
+
+From: SeongJae Park <sj@kernel.org>
+
+[ Upstream commit 85506aca2eb4ea41223c91c5fe25125953c19b13 ]
+
+While mq_perf_tests runs with the default kselftest timeout limit, which
+is 45 seconds, the test takes about 60 seconds to complete on i3.metal
+AWS instances. Hence, the test always times out. Increase the timeout
+to 180 seconds.
+
+Fixes: 852c8cbf34d3 ("selftests/kselftest/runner.sh: Add 45 second timeout per test")
+Cc: <stable@vger.kernel.org> # 5.4.x
+Signed-off-by: SeongJae Park <sj@kernel.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/mqueue/setting | 1 +
+ 1 file changed, 1 insertion(+)
+ create mode 100644 tools/testing/selftests/mqueue/setting
+
+diff --git a/tools/testing/selftests/mqueue/setting b/tools/testing/selftests/mqueue/setting
+new file mode 100644
+index 0000000000000..a953c96aa16e1
+--- /dev/null
++++ b/tools/testing/selftests/mqueue/setting
+@@ -0,0 +1 @@
++timeout=180
+--
+2.43.0
+
--- /dev/null
+From 6cbdbcb97347d63b9c5f862e0578e77070493500 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Jan 2024 10:21:57 -0500
+Subject: serial: max310x: fix NULL pointer dereference in I2C instantiation
+
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+
+[ Upstream commit 0d27056c24efd3d63a03f3edfbcfc4827086b110 ]
+
+When trying to instantiate a max14830 device from userspace:
+
+ echo max14830 0x60 > /sys/bus/i2c/devices/i2c-2/new_device
+
+we get the following error:
+
+ Unable to handle kernel NULL pointer dereference at virtual address...
+ ...
+ Call trace:
+ max310x_i2c_probe+0x48/0x170 [max310x]
+ i2c_device_probe+0x150/0x2a0
+ ...
+
+Add check for validity of devtype to prevent the error, and abort probe
+with a meaningful error message.
+
+Fixes: 2e1f2d9a9bdb ("serial: max310x: implement I2C support")
+Cc: stable@vger.kernel.org
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Link: https://lore.kernel.org/r/20240118152213.2644269-2-hugo@hugovil.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/max310x.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
+index 5570fd3b84e15..363b68555fe62 100644
+--- a/drivers/tty/serial/max310x.c
++++ b/drivers/tty/serial/max310x.c
+@@ -1636,13 +1636,16 @@ static unsigned short max310x_i2c_slave_addr(unsigned short addr,
+
+ static int max310x_i2c_probe(struct i2c_client *client)
+ {
+- const struct max310x_devtype *devtype =
+- device_get_match_data(&client->dev);
++ const struct max310x_devtype *devtype;
+ struct i2c_client *port_client;
+ struct regmap *regmaps[4];
+ unsigned int i;
+ u8 port_addr;
+
++ devtype = device_get_match_data(&client->dev);
++ if (!devtype)
++ return dev_err_probe(&client->dev, -ENODEV, "Failed to match device\n");
++
+ if (client->addr < devtype->slave_addr.min ||
+ client->addr > devtype->slave_addr.max)
+ return dev_err_probe(&client->dev, -EINVAL,
+--
+2.43.0
+
documentation-hw-vuln-update-spectre-doc.patch
x86-cpu-support-amd-automatic-ibrs.patch
x86-bugs-use-sysfs_emit.patch
+timers-update-kernel-doc-for-various-functions.patch
+timers-use-del_timer_sync-even-on-up.patch
+timers-rename-del_timer_sync-to-timer_delete_sync.patch
+wifi-brcmfmac-fix-use-after-free-bug-in-brcmf_cfg802.patch
+media-staging-ipu3-imgu-set-fields-before-media_enti.patch
+clk-qcom-gcc-sdm845-add-soft-dependency-on-rpmhpd.patch
+smack-set-smack64transmute-only-for-dirs-in-smack_in.patch
+smack-handle-smack64transmute-in-smack_inode_setsecu.patch
+arm-dts-mmp2-brownstone-don-t-redeclare-phandle-refe.patch
+arm-dts-marvell-fix-maxium-maxim-typo-in-brownstone-.patch
+serial-max310x-fix-null-pointer-dereference-in-i2c-i.patch
+media-xc4000-fix-atomicity-violation-in-xc4000_get_f.patch
+kvm-always-flush-async-pf-workqueue-when-vcpu-is-bei.patch
+sparc64-nmi-watchdog-fix-return-value-of-__setup-han.patch
+sparc-vdso-fix-return-value-of-__setup-handler.patch
+crypto-qat-fix-double-free-during-reset.patch
+crypto-qat-resolve-race-condition-during-aer-recover.patch
+selftests-mqueue-set-timeout-to-180-seconds.patch
+ext4-correct-best-extent-lstart-adjustment-logic.patch
+fat-fix-uninitialized-field-in-nostale-filehandles.patch
+ubifs-set-page-uptodate-in-the-correct-place.patch
+ubi-check-for-too-small-leb-size-in-vtbl-code.patch
+ubi-correct-the-calculation-of-fastmap-size.patch
+mtd-rawnand-meson-fix-scrambling-mode-value-in-comma.patch
+parisc-do-not-hardcode-registers-in-checksum-functio.patch
+parisc-fix-ip_fast_csum.patch
+parisc-fix-csum_ipv6_magic-on-32-bit-systems.patch
+parisc-fix-csum_ipv6_magic-on-64-bit-systems.patch
+parisc-strip-upper-32-bit-of-sum-in-csum_ipv6_magic-.patch
+pm-suspend-set-mem_sleep_current-during-kernel-comma.patch
+clk-qcom-gcc-ipq8074-fix-terminating-of-frequency-ta.patch
+clk-qcom-mmcc-apq8084-fix-terminating-of-frequency-t.patch
+clk-qcom-mmcc-msm8974-fix-terminating-of-frequency-t.patch
+powerpc-fsl-fix-mfpmr-build-errors-with-newer-binuti.patch
+usb-serial-ftdi_sio-add-support-for-gmc-z216c-adapte.patch
+usb-serial-add-device-id-for-verifone-adapter.patch
+usb-serial-cp210x-add-id-for-mgp-instruments-pds100.patch
+usb-serial-option-add-meig-smart-slm320-product.patch
+usb-serial-cp210x-add-pid-vid-for-tdk-nc0110013m-and.patch
+pm-sleep-wakeirq-fix-wake-irq-warning-in-system-susp.patch
+mmc-tmio-avoid-concurrent-runs-of-mmc_request_done.patch
+fuse-store-fuse_conn-in-fuse_req.patch
+fuse-drop-fuse_conn-parameter-where-possible.patch
+fuse-don-t-unhash-root.patch
+btrfs-fix-off-by-one-chunk-length-calculation-at-con.patch
+pci-drop-pci_device_remove-test-of-pci_dev-driver.patch
+pci-pm-drain-runtime-idle-callbacks-before-driver-re.patch
+revert-revert-md-raid5-wait-for-md_sb_change_pending.patch
+dm-raid-fix-lockdep-waring-in-pers-hot_add_disk.patch
+mmc-core-fix-switch-on-gp3-partition.patch
+hwmon-amc6821-add-of_match-table.patch
+ext4-fix-corruption-during-on-line-resize.patch
+firmware-meson_sm-rework-driver-as-a-proper-platform.patch
+nvmem-meson-efuse-fix-function-pointer-type-mismatch.patch
+slimbus-core-remove-usage-of-the-deprecated-ida_simp.patch
+speakup-fix-8bit-characters-from-direct-synth.patch
+kbuild-move-wenum-compare-conditional-enum-conversio.patch
+vfio-platform-disable-virqfds-on-cleanup.patch
+ring-buffer-fix-resetting-of-shortest_full.patch
+ring-buffer-fix-full_waiters_pending-in-poll.patch
+soc-fsl-qbman-always-disable-interrupts-when-taking-.patch
+soc-fsl-qbman-add-helper-for-sanity-checking-cgr-ops.patch
+soc-fsl-qbman-add-cgr-update-function.patch
+soc-fsl-qbman-use-raw-spinlock-for-cgr_lock.patch
+s390-zcrypt-fix-reference-counting-on-zcrypt-card-ob.patch
+drm-exynos-do-not-return-negative-values-from-.get_m.patch
+drm-imx-ipuv3-do-not-return-negative-values-from-.ge.patch
+drm-vc4-hdmi-do-not-return-negative-values-from-.get.patch
+memtest-use-read-write-_once-in-memory-scanning.patch
+nilfs2-fix-failure-to-detect-dat-corruption-in-btree.patch
+nilfs2-use-a-more-common-logging-style.patch
+nilfs2-prevent-kernel-bug-at-submit_bh_wbc.patch
+x86-cpu-amd-update-the-zenbleed-microcode-revisions.patch
+ahci-asm1064-correct-count-of-reported-ports.patch
+ahci-asm1064-asm1166-don-t-limit-reported-ports.patch
+dm-snapshot-fix-lockup-in-dm_exception_table_exit.patch
--- /dev/null
+From 25a714379a4f2db9b08e8f2def20f07d2105a37e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 Feb 2024 11:41:37 +0000
+Subject: slimbus: core: Remove usage of the deprecated ida_simple_xx() API
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 89ffa4cccec54467446f141a79b9e36893079fb8 ]
+
+ida_alloc() and ida_free() should be preferred to the deprecated
+ida_simple_get() and ida_simple_remove().
+
+Note that the upper limit of ida_simple_get() is exclusive, but the one of
+ida_alloc_range() is inclusive. So change this change allows one more
+device. Previously address 0xFE was never used.
+
+Fixes: 46a2bb5a7f7e ("slimbus: core: Add slim controllers support")
+Cc: Stable@vger.kernel.org
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114137.85781-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/slimbus/core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/slimbus/core.c b/drivers/slimbus/core.c
+index 130c798921b5d..e3f3ce6dc7e74 100644
+--- a/drivers/slimbus/core.c
++++ b/drivers/slimbus/core.c
+@@ -439,8 +439,8 @@ static int slim_device_alloc_laddr(struct slim_device *sbdev,
+ if (ret < 0)
+ goto err;
+ } else if (report_present) {
+- ret = ida_simple_get(&ctrl->laddr_ida,
+- 0, SLIM_LA_MANAGER - 1, GFP_KERNEL);
++ ret = ida_alloc_max(&ctrl->laddr_ida,
++ SLIM_LA_MANAGER - 1, GFP_KERNEL);
+ if (ret < 0)
+ goto err;
+
+--
+2.43.0
+
--- /dev/null
+From 1f65e09d10b7acbfdc2a827677532b0bde616b2c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Nov 2023 10:01:22 +0100
+Subject: smack: Handle SMACK64TRANSMUTE in smack_inode_setsecurity()
+
+From: Roberto Sassu <roberto.sassu@huawei.com>
+
+[ Upstream commit ac02f007d64eb2769d0bde742aac4d7a5fc6e8a5 ]
+
+If the SMACK64TRANSMUTE xattr is provided, and the inode is a directory,
+update the in-memory inode flags by setting SMK_INODE_TRANSMUTE.
+
+Cc: stable@vger.kernel.org
+Fixes: 5c6d1125f8db ("Smack: Transmute labels on specified directories") # v2.6.38.x
+Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/smack/smack_lsm.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index 65743be5b30f5..072ce1ef6efb7 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -2717,6 +2717,15 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
+ if (value == NULL || size > SMK_LONGLABEL || size == 0)
+ return -EINVAL;
+
++ if (strcmp(name, XATTR_SMACK_TRANSMUTE) == 0) {
++ if (!S_ISDIR(inode->i_mode) || size != TRANS_TRUE_SIZE ||
++ strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
++ return -EINVAL;
++
++ nsp->smk_flags |= SMK_INODE_TRANSMUTE;
++ return 0;
++ }
++
+ skp = smk_import_entry(value, size);
+ if (IS_ERR(skp))
+ return PTR_ERR(skp);
+--
+2.43.0
+
--- /dev/null
+From 6181e4fddf0626f3326dd7c2c29fbfd8d805e162 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Nov 2023 10:01:21 +0100
+Subject: smack: Set SMACK64TRANSMUTE only for dirs in smack_inode_setxattr()
+
+From: Roberto Sassu <roberto.sassu@huawei.com>
+
+[ Upstream commit 9c82169208dde516510aaba6bbd8b13976690c5d ]
+
+Since the SMACK64TRANSMUTE xattr makes sense only for directories, enforce
+this restriction in smack_inode_setxattr().
+
+Cc: stable@vger.kernel.org
+Fixes: 5c6d1125f8db ("Smack: Transmute labels on specified directories") # v2.6.38.x
+Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
+Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/smack/smack_lsm.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
+index 6f2613f874fa9..65743be5b30f5 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -1290,7 +1290,8 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
+ check_star = 1;
+ } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
+ check_priv = 1;
+- if (size != TRANS_TRUE_SIZE ||
++ if (!S_ISDIR(d_backing_inode(dentry)->i_mode) ||
++ size != TRANS_TRUE_SIZE ||
+ strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
+ rc = -EINVAL;
+ } else
+--
+2.43.0
+
--- /dev/null
+From f7b06ebac72817826ed8775116e7504d0ea57fb0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Sep 2022 17:57:35 -0400
+Subject: soc: fsl: qbman: Add CGR update function
+
+From: Sean Anderson <sean.anderson@seco.com>
+
+[ Upstream commit 914f8b228ede709274b8c80514b352248ec9da00 ]
+
+This adds a function to update a CGR with new parameters. qman_create_cgr
+can almost be used for this (with flags=0), but it's not suitable because
+it also registers the callback function. The _safe variant was modeled off
+of qman_cgr_delete_safe. However, we handle multiple arguments and a return
+value.
+
+Signed-off-by: Sean Anderson <sean.anderson@seco.com>
+Acked-by: Camelia Groza <camelia.groza@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: fbec4e7fed89 ("soc: fsl: qbman: Use raw spinlock for cgr_lock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/fsl/qbman/qman.c | 48 ++++++++++++++++++++++++++++++++++++
+ include/soc/fsl/qman.h | 9 +++++++
+ 2 files changed, 57 insertions(+)
+
+diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
+index e31d33d000526..52327f0dab986 100644
+--- a/drivers/soc/fsl/qbman/qman.c
++++ b/drivers/soc/fsl/qbman/qman.c
+@@ -2566,6 +2566,54 @@ void qman_delete_cgr_safe(struct qman_cgr *cgr)
+ }
+ EXPORT_SYMBOL(qman_delete_cgr_safe);
+
++static int qman_update_cgr(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts)
++{
++ int ret;
++ unsigned long irqflags;
++ struct qman_portal *p = qman_cgr_get_affine_portal(cgr);
++
++ if (!p)
++ return -EINVAL;
++
++ spin_lock_irqsave(&p->cgr_lock, irqflags);
++ ret = qm_modify_cgr(cgr, 0, opts);
++ spin_unlock_irqrestore(&p->cgr_lock, irqflags);
++ put_affine_portal();
++ return ret;
++}
++
++struct update_cgr_params {
++ struct qman_cgr *cgr;
++ struct qm_mcc_initcgr *opts;
++ int ret;
++};
++
++static void qman_update_cgr_smp_call(void *p)
++{
++ struct update_cgr_params *params = p;
++
++ params->ret = qman_update_cgr(params->cgr, params->opts);
++}
++
++int qman_update_cgr_safe(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts)
++{
++ struct update_cgr_params params = {
++ .cgr = cgr,
++ .opts = opts,
++ };
++
++ preempt_disable();
++ if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id())
++ smp_call_function_single(qman_cgr_cpus[cgr->cgrid],
++ qman_update_cgr_smp_call, ¶ms,
++ true);
++ else
++ params.ret = qman_update_cgr(cgr, opts);
++ preempt_enable();
++ return params.ret;
++}
++EXPORT_SYMBOL(qman_update_cgr_safe);
++
+ /* Cleanup FQs */
+
+ static int _qm_mr_consume_and_match_verb(struct qm_portal *p, int v)
+diff --git a/include/soc/fsl/qman.h b/include/soc/fsl/qman.h
+index aa31c05a103ad..f9c622027d852 100644
+--- a/include/soc/fsl/qman.h
++++ b/include/soc/fsl/qman.h
+@@ -1159,6 +1159,15 @@ int qman_delete_cgr(struct qman_cgr *cgr);
+ */
+ void qman_delete_cgr_safe(struct qman_cgr *cgr);
+
++/**
++ * qman_update_cgr_safe - Modifies a congestion group object from any CPU
++ * @cgr: the 'cgr' object to modify
++ * @opts: state of the CGR settings
++ *
++ * This will select the proper CPU and modify the CGR settings.
++ */
++int qman_update_cgr_safe(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts);
++
+ /**
+ * qman_query_cgr_congested - Queries CGR's congestion status
+ * @cgr: the 'cgr' object to query
+--
+2.43.0
+
--- /dev/null
+From 36f2b30bda2babe5670512ab26e4afbdd420c7e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Sep 2022 17:57:34 -0400
+Subject: soc: fsl: qbman: Add helper for sanity checking cgr ops
+
+From: Sean Anderson <sean.anderson@seco.com>
+
+[ Upstream commit d0e17a4653cebc2c8a20251c837dd1fcec5014d9 ]
+
+This breaks out/combines get_affine_portal and the cgr sanity check in
+preparation for the next commit. No functional change intended.
+
+Signed-off-by: Sean Anderson <sean.anderson@seco.com>
+Acked-by: Camelia Groza <camelia.groza@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: fbec4e7fed89 ("soc: fsl: qbman: Use raw spinlock for cgr_lock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/fsl/qbman/qman.c | 29 +++++++++++++++++++----------
+ 1 file changed, 19 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
+index 53b4cd0fb662d..e31d33d000526 100644
+--- a/drivers/soc/fsl/qbman/qman.c
++++ b/drivers/soc/fsl/qbman/qman.c
+@@ -2481,13 +2481,8 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
+ }
+ EXPORT_SYMBOL(qman_create_cgr);
+
+-int qman_delete_cgr(struct qman_cgr *cgr)
++static struct qman_portal *qman_cgr_get_affine_portal(struct qman_cgr *cgr)
+ {
+- unsigned long irqflags;
+- struct qm_mcr_querycgr cgr_state;
+- struct qm_mcc_initcgr local_opts;
+- int ret = 0;
+- struct qman_cgr *i;
+ struct qman_portal *p = get_affine_portal();
+
+ if (cgr->chan != p->config->channel) {
+@@ -2495,10 +2490,25 @@ int qman_delete_cgr(struct qman_cgr *cgr)
+ dev_err(p->config->dev, "CGR not owned by current portal");
+ dev_dbg(p->config->dev, " create 0x%x, delete 0x%x\n",
+ cgr->chan, p->config->channel);
+-
+- ret = -EINVAL;
+- goto put_portal;
++ put_affine_portal();
++ return NULL;
+ }
++
++ return p;
++}
++
++int qman_delete_cgr(struct qman_cgr *cgr)
++{
++ unsigned long irqflags;
++ struct qm_mcr_querycgr cgr_state;
++ struct qm_mcc_initcgr local_opts;
++ int ret = 0;
++ struct qman_cgr *i;
++ struct qman_portal *p = qman_cgr_get_affine_portal(cgr);
++
++ if (!p)
++ return -EINVAL;
++
+ memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
+ spin_lock_irqsave(&p->cgr_lock, irqflags);
+ list_del(&cgr->node);
+@@ -2526,7 +2536,6 @@ int qman_delete_cgr(struct qman_cgr *cgr)
+ list_add(&cgr->node, &p->cgr_cbs);
+ release_lock:
+ spin_unlock_irqrestore(&p->cgr_lock, irqflags);
+-put_portal:
+ put_affine_portal();
+ return ret;
+ }
+--
+2.43.0
+
--- /dev/null
+From 1c17f923ba1446a1d07b8191aac3d4b73103f2fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Mar 2024 12:38:29 -0400
+Subject: soc: fsl: qbman: Always disable interrupts when taking cgr_lock
+
+From: Sean Anderson <sean.anderson@linux.dev>
+
+[ Upstream commit 584c2a9184a33a40fceee838f856de3cffa19be3 ]
+
+smp_call_function_single disables IRQs when executing the callback. To
+prevent deadlocks, we must disable IRQs when taking cgr_lock elsewhere.
+This is already done by qman_update_cgr and qman_delete_cgr; fix the
+other lockers.
+
+Fixes: 96f413f47677 ("soc/fsl/qbman: fix issue in qman_delete_cgr_safe()")
+CC: stable@vger.kernel.org
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Reviewed-by: Camelia Groza <camelia.groza@nxp.com>
+Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/fsl/qbman/qman.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
+index 95f9e48052452..53b4cd0fb662d 100644
+--- a/drivers/soc/fsl/qbman/qman.c
++++ b/drivers/soc/fsl/qbman/qman.c
+@@ -1461,11 +1461,11 @@ static void qm_congestion_task(struct work_struct *work)
+ union qm_mc_result *mcr;
+ struct qman_cgr *cgr;
+
+- spin_lock(&p->cgr_lock);
++ spin_lock_irq(&p->cgr_lock);
+ qm_mc_start(&p->p);
+ qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
+ if (!qm_mc_result_timeout(&p->p, &mcr)) {
+- spin_unlock(&p->cgr_lock);
++ spin_unlock_irq(&p->cgr_lock);
+ dev_crit(p->config->dev, "QUERYCONGESTION timeout\n");
+ qman_p_irqsource_add(p, QM_PIRQ_CSCI);
+ return;
+@@ -1481,7 +1481,7 @@ static void qm_congestion_task(struct work_struct *work)
+ list_for_each_entry(cgr, &p->cgr_cbs, node)
+ if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
+ cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
+- spin_unlock(&p->cgr_lock);
++ spin_unlock_irq(&p->cgr_lock);
+ qman_p_irqsource_add(p, QM_PIRQ_CSCI);
+ }
+
+@@ -2438,7 +2438,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
+ preempt_enable();
+
+ cgr->chan = p->config->channel;
+- spin_lock(&p->cgr_lock);
++ spin_lock_irq(&p->cgr_lock);
+
+ if (opts) {
+ struct qm_mcc_initcgr local_opts = *opts;
+@@ -2475,7 +2475,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
+ qman_cgrs_get(&p->cgrs[1], cgr->cgrid))
+ cgr->cb(p, cgr, 1);
+ out:
+- spin_unlock(&p->cgr_lock);
++ spin_unlock_irq(&p->cgr_lock);
+ put_affine_portal();
+ return ret;
+ }
+--
+2.43.0
+
--- /dev/null
+From 5416903522a8e4d81bafa69e3848ad9823618da1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Mar 2024 12:38:30 -0400
+Subject: soc: fsl: qbman: Use raw spinlock for cgr_lock
+
+From: Sean Anderson <sean.anderson@linux.dev>
+
+[ Upstream commit fbec4e7fed89b579f2483041fabf9650fb0dd6bc ]
+
+smp_call_function always runs its callback in hard IRQ context, even on
+PREEMPT_RT, where spinlocks can sleep. So we need to use a raw spinlock
+for cgr_lock to ensure we aren't waiting on a sleeping task.
+
+Although this bug has existed for a while, it was not apparent until
+commit ef2a8d5478b9 ("net: dpaa: Adjust queue depth on rate change")
+which invokes smp_call_function_single via qman_update_cgr_safe every
+time a link goes up or down.
+
+Fixes: 96f413f47677 ("soc/fsl/qbman: fix issue in qman_delete_cgr_safe()")
+CC: stable@vger.kernel.org
+Reported-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Closes: https://lore.kernel.org/all/20230323153935.nofnjucqjqnz34ej@skbuf/
+Reported-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
+Closes: https://lore.kernel.org/linux-arm-kernel/87wmsyvclu.fsf@pengutronix.de/
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Reviewed-by: Camelia Groza <camelia.groza@nxp.com>
+Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/fsl/qbman/qman.c | 25 ++++++++++++++-----------
+ 1 file changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
+index 52327f0dab986..5144b8c66ac46 100644
+--- a/drivers/soc/fsl/qbman/qman.c
++++ b/drivers/soc/fsl/qbman/qman.c
+@@ -996,7 +996,7 @@ struct qman_portal {
+ /* linked-list of CSCN handlers. */
+ struct list_head cgr_cbs;
+ /* list lock */
+- spinlock_t cgr_lock;
++ raw_spinlock_t cgr_lock;
+ struct work_struct congestion_work;
+ struct work_struct mr_work;
+ char irqname[MAX_IRQNAME];
+@@ -1286,7 +1286,7 @@ static int qman_create_portal(struct qman_portal *portal,
+ /* if the given mask is NULL, assume all CGRs can be seen */
+ qman_cgrs_fill(&portal->cgrs[0]);
+ INIT_LIST_HEAD(&portal->cgr_cbs);
+- spin_lock_init(&portal->cgr_lock);
++ raw_spin_lock_init(&portal->cgr_lock);
+ INIT_WORK(&portal->congestion_work, qm_congestion_task);
+ INIT_WORK(&portal->mr_work, qm_mr_process_task);
+ portal->bits = 0;
+@@ -1461,11 +1461,14 @@ static void qm_congestion_task(struct work_struct *work)
+ union qm_mc_result *mcr;
+ struct qman_cgr *cgr;
+
+- spin_lock_irq(&p->cgr_lock);
++ /*
++ * FIXME: QM_MCR_TIMEOUT is 10ms, which is too long for a raw spinlock!
++ */
++ raw_spin_lock_irq(&p->cgr_lock);
+ qm_mc_start(&p->p);
+ qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
+ if (!qm_mc_result_timeout(&p->p, &mcr)) {
+- spin_unlock_irq(&p->cgr_lock);
++ raw_spin_unlock_irq(&p->cgr_lock);
+ dev_crit(p->config->dev, "QUERYCONGESTION timeout\n");
+ qman_p_irqsource_add(p, QM_PIRQ_CSCI);
+ return;
+@@ -1481,7 +1484,7 @@ static void qm_congestion_task(struct work_struct *work)
+ list_for_each_entry(cgr, &p->cgr_cbs, node)
+ if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
+ cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
+- spin_unlock_irq(&p->cgr_lock);
++ raw_spin_unlock_irq(&p->cgr_lock);
+ qman_p_irqsource_add(p, QM_PIRQ_CSCI);
+ }
+
+@@ -2438,7 +2441,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
+ preempt_enable();
+
+ cgr->chan = p->config->channel;
+- spin_lock_irq(&p->cgr_lock);
++ raw_spin_lock_irq(&p->cgr_lock);
+
+ if (opts) {
+ struct qm_mcc_initcgr local_opts = *opts;
+@@ -2475,7 +2478,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
+ qman_cgrs_get(&p->cgrs[1], cgr->cgrid))
+ cgr->cb(p, cgr, 1);
+ out:
+- spin_unlock_irq(&p->cgr_lock);
++ raw_spin_unlock_irq(&p->cgr_lock);
+ put_affine_portal();
+ return ret;
+ }
+@@ -2510,7 +2513,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
+ return -EINVAL;
+
+ memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
+- spin_lock_irqsave(&p->cgr_lock, irqflags);
++ raw_spin_lock_irqsave(&p->cgr_lock, irqflags);
+ list_del(&cgr->node);
+ /*
+ * If there are no other CGR objects for this CGRID in the list,
+@@ -2535,7 +2538,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
+ /* add back to the list */
+ list_add(&cgr->node, &p->cgr_cbs);
+ release_lock:
+- spin_unlock_irqrestore(&p->cgr_lock, irqflags);
++ raw_spin_unlock_irqrestore(&p->cgr_lock, irqflags);
+ put_affine_portal();
+ return ret;
+ }
+@@ -2575,9 +2578,9 @@ static int qman_update_cgr(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts)
+ if (!p)
+ return -EINVAL;
+
+- spin_lock_irqsave(&p->cgr_lock, irqflags);
++ raw_spin_lock_irqsave(&p->cgr_lock, irqflags);
+ ret = qm_modify_cgr(cgr, 0, opts);
+- spin_unlock_irqrestore(&p->cgr_lock, irqflags);
++ raw_spin_unlock_irqrestore(&p->cgr_lock, irqflags);
+ put_affine_portal();
+ return ret;
+ }
+--
+2.43.0
+
--- /dev/null
+From 6e73b9c1ea4246a99b1dc6744f644971b218fad2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Feb 2024 21:28:08 -0800
+Subject: sparc: vDSO: fix return value of __setup handler
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 5378f00c935bebb846b1fdb0e79cb76c137c56b5 ]
+
+__setup() handlers should return 1 to obsolete_checksetup() in
+init/main.c to indicate that the boot option has been handled.
+A return of 0 causes the boot option/value to be listed as an Unknown
+kernel parameter and added to init's (limited) argument or environment
+strings. Also, error return codes don't mean anything to
+obsolete_checksetup() -- only non-zero (usually 1) or zero.
+So return 1 from vdso_setup().
+
+Fixes: 9a08862a5d2e ("vDSO for sparc")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Reported-by: Igor Zhbanov <izh1979@gmail.com>
+Link: lore.kernel.org/r/64644a2f-4a20-bab3-1e15-3b2cdd0defe3@omprussia.ru
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: sparclinux@vger.kernel.org
+Cc: Dan Carpenter <dan.carpenter@oracle.com>
+Cc: Nick Alcock <nick.alcock@oracle.com>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: stable@vger.kernel.org
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Andreas Larsson <andreas@gaisler.com>
+Signed-off-by: Andreas Larsson <andreas@gaisler.com>
+Link: https://lore.kernel.org/r/20240211052808.22635-1-rdunlap@infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/sparc/vdso/vma.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/arch/sparc/vdso/vma.c b/arch/sparc/vdso/vma.c
+index 9961b0f816939..3a30a086f0feb 100644
+--- a/arch/sparc/vdso/vma.c
++++ b/arch/sparc/vdso/vma.c
+@@ -449,9 +449,8 @@ static __init int vdso_setup(char *s)
+ unsigned long val;
+
+ err = kstrtoul(s, 10, &val);
+- if (err)
+- return err;
+- vdso_enabled = val;
+- return 0;
++ if (!err)
++ vdso_enabled = val;
++ return 1;
+ }
+ __setup("vdso=", vdso_setup);
+--
+2.43.0
+
--- /dev/null
+From 8d0f8fd50a80723f82586df4d14cae56de5f2ccc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 10 Feb 2024 21:28:02 -0800
+Subject: sparc64: NMI watchdog: fix return value of __setup handler
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 3ed7c61e49d65dacb96db798c0ab6fcd55a1f20f ]
+
+__setup() handlers should return 1 to obsolete_checksetup() in
+init/main.c to indicate that the boot option has been handled.
+A return of 0 causes the boot option/value to be listed as an Unknown
+kernel parameter and added to init's (limited) argument or environment
+strings. Also, error return codes don't mean anything to
+obsolete_checksetup() -- only non-zero (usually 1) or zero.
+So return 1 from setup_nmi_watchdog().
+
+Fixes: e5553a6d0442 ("sparc64: Implement NMI watchdog on capable cpus.")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Reported-by: Igor Zhbanov <izh1979@gmail.com>
+Link: lore.kernel.org/r/64644a2f-4a20-bab3-1e15-3b2cdd0defe3@omprussia.ru
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: sparclinux@vger.kernel.org
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: stable@vger.kernel.org
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Andreas Larsson <andreas@gaisler.com>
+Signed-off-by: Andreas Larsson <andreas@gaisler.com>
+Link: https://lore.kernel.org/r/20240211052802.22612-1-rdunlap@infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/sparc/kernel/nmi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c
+index 060fff95a305c..fbf25e926f67c 100644
+--- a/arch/sparc/kernel/nmi.c
++++ b/arch/sparc/kernel/nmi.c
+@@ -274,7 +274,7 @@ static int __init setup_nmi_watchdog(char *str)
+ if (!strncmp(str, "panic", 5))
+ panic_on_timeout = 1;
+
+- return 0;
++ return 1;
+ }
+ __setup("nmi_watchdog=", setup_nmi_watchdog);
+
+--
+2.43.0
+
--- /dev/null
+From 27e7aa172d013063ed9e54f39dd942990f121bcc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 4 Feb 2024 16:57:36 +0100
+Subject: speakup: Fix 8bit characters from direct synth
+
+From: Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+[ Upstream commit b6c8dafc9d86eb77e502bb018ec4105e8d2fbf78 ]
+
+When userland echoes 8bit characters to /dev/synth with e.g.
+
+echo -e '\xe9' > /dev/synth
+
+synth_write would get characters beyond 0x7f, and thus negative when
+char is signed. When given to synth_buffer_add which takes a u16, this
+would sign-extend and produce a U+ffxy character rather than U+xy.
+Users thus get garbled text instead of accents in their output.
+
+Let's fix this by making sure that we read unsigned characters.
+
+Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
+Fixes: 89fc2ae80bb1 ("speakup: extend synth buffer to 16bit unicode characters")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240204155736.2oh4ot7tiaa2wpbh@begin
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/staging/speakup/synth.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/speakup/synth.c b/drivers/staging/speakup/synth.c
+index 3568bfb89912c..b5944e7bdbf67 100644
+--- a/drivers/staging/speakup/synth.c
++++ b/drivers/staging/speakup/synth.c
+@@ -208,8 +208,10 @@ void spk_do_flush(void)
+ wake_up_process(speakup_task);
+ }
+
+-void synth_write(const char *buf, size_t count)
++void synth_write(const char *_buf, size_t count)
+ {
++ const unsigned char *buf = (const unsigned char *) _buf;
++
+ while (count--)
+ synth_buffer_add(*buf++);
+ synth_start();
+--
+2.43.0
+
--- /dev/null
+From f11327fe09afd2f77c6c2590491b7ab1bd9f7a78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 21:18:44 +0100
+Subject: timers: Rename del_timer_sync() to timer_delete_sync()
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 9b13df3fb64ee95e2397585404e442afee2c7d4f ]
+
+The timer related functions do not have a strict timer_ prefixed namespace
+which is really annoying.
+
+Rename del_timer_sync() to timer_delete_sync() and provide del_timer_sync()
+as a wrapper. Document that del_timer_sync() is not for new code.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+Link: https://lore.kernel.org/r/20221123201624.954785441@linutronix.de
+Stable-dep-of: 0f7352557a35 ("wifi: brcmfmac: Fix use-after-free bug in brcmf_cfg80211_detach")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/timer.h | 15 ++++++++++++++-
+ kernel/time/timer.c | 18 +++++++++---------
+ 2 files changed, 23 insertions(+), 10 deletions(-)
+
+diff --git a/include/linux/timer.h b/include/linux/timer.h
+index 4de865f516154..cadb23acd229e 100644
+--- a/include/linux/timer.h
++++ b/include/linux/timer.h
+@@ -182,7 +182,20 @@ extern int timer_reduce(struct timer_list *timer, unsigned long expires);
+ extern void add_timer(struct timer_list *timer);
+
+ extern int try_to_del_timer_sync(struct timer_list *timer);
+-extern int del_timer_sync(struct timer_list *timer);
++extern int timer_delete_sync(struct timer_list *timer);
++
++/**
++ * del_timer_sync - Delete a pending timer and wait for a running callback
++ * @timer: The timer to be deleted
++ *
++ * See timer_delete_sync() for detailed explanation.
++ *
++ * Do not use in new code. Use timer_delete_sync() instead.
++ */
++static inline int del_timer_sync(struct timer_list *timer)
++{
++ return timer_delete_sync(timer);
++}
+
+ #define del_singleshot_timer_sync(t) del_timer_sync(t)
+
+diff --git a/kernel/time/timer.c b/kernel/time/timer.c
+index 0dfd1cacc4a00..6e2dd83a93afd 100644
+--- a/kernel/time/timer.c
++++ b/kernel/time/timer.c
+@@ -1031,7 +1031,7 @@ __mod_timer(struct timer_list *timer, unsigned long expires, unsigned int option
+ /*
+ * We are trying to schedule the timer on the new base.
+ * However we can't change timer's base while it is running,
+- * otherwise del_timer_sync() can't detect that the timer's
++ * otherwise timer_delete_sync() can't detect that the timer's
+ * handler yet has not finished. This also guarantees that the
+ * timer is serialized wrt itself.
+ */
+@@ -1210,7 +1210,7 @@ EXPORT_SYMBOL_GPL(add_timer_on);
+ * @timer: The timer to be deactivated
+ *
+ * The function only deactivates a pending timer, but contrary to
+- * del_timer_sync() it does not take into account whether the timer's
++ * timer_delete_sync() it does not take into account whether the timer's
+ * callback function is concurrently executed on a different CPU or not.
+ * It neither prevents rearming of the timer. If @timer can be rearmed
+ * concurrently then the return value of this function is meaningless.
+@@ -1346,7 +1346,7 @@ static inline void del_timer_wait_running(struct timer_list *timer) { }
+ #endif
+
+ /**
+- * del_timer_sync - Deactivate a timer and wait for the handler to finish.
++ * timer_delete_sync - Deactivate a timer and wait for the handler to finish.
+ * @timer: The timer to be deactivated
+ *
+ * Synchronization rules: Callers must prevent restarting of the timer,
+@@ -1368,10 +1368,10 @@ static inline void del_timer_wait_running(struct timer_list *timer) { }
+ * spin_lock_irq(somelock);
+ * <IRQ>
+ * spin_lock(somelock);
+- * del_timer_sync(mytimer);
++ * timer_delete_sync(mytimer);
+ * while (base->running_timer == mytimer);
+ *
+- * Now del_timer_sync() will never return and never release somelock.
++ * Now timer_delete_sync() will never return and never release somelock.
+ * The interrupt on the other CPU is waiting to grab somelock but it has
+ * interrupted the softirq that CPU0 is waiting to finish.
+ *
+@@ -1384,7 +1384,7 @@ static inline void del_timer_wait_running(struct timer_list *timer) { }
+ * * %0 - The timer was not pending
+ * * %1 - The timer was pending and deactivated
+ */
+-int del_timer_sync(struct timer_list *timer)
++int timer_delete_sync(struct timer_list *timer)
+ {
+ int ret;
+
+@@ -1417,7 +1417,7 @@ int del_timer_sync(struct timer_list *timer)
+
+ return ret;
+ }
+-EXPORT_SYMBOL(del_timer_sync);
++EXPORT_SYMBOL(timer_delete_sync);
+
+ static void call_timer_fn(struct timer_list *timer,
+ void (*fn)(struct timer_list *),
+@@ -1439,8 +1439,8 @@ static void call_timer_fn(struct timer_list *timer,
+ #endif
+ /*
+ * Couple the lock chain with the lock chain at
+- * del_timer_sync() by acquiring the lock_map around the fn()
+- * call here and in del_timer_sync().
++ * timer_delete_sync() by acquiring the lock_map around the fn()
++ * call here and in timer_delete_sync().
+ */
+ lock_map_acquire(&lockdep_map);
+
+--
+2.43.0
+
--- /dev/null
+From 237136958798e092e09ee7c8f61fd89f7744d3b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 21:18:40 +0100
+Subject: timers: Update kernel-doc for various functions
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 14f043f1340bf30bc60af127bff39f55889fef26 ]
+
+The kernel-doc of timer related functions is partially uncomprehensible
+word salad. Rewrite it to make it useful.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+Link: https://lore.kernel.org/r/20221123201624.828703870@linutronix.de
+Stable-dep-of: 0f7352557a35 ("wifi: brcmfmac: Fix use-after-free bug in brcmf_cfg80211_detach")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/timer.c | 148 +++++++++++++++++++++++++++-----------------
+ 1 file changed, 90 insertions(+), 58 deletions(-)
+
+diff --git a/kernel/time/timer.c b/kernel/time/timer.c
+index 16a2b62f5f74c..973c66d9b3f90 100644
+--- a/kernel/time/timer.c
++++ b/kernel/time/timer.c
+@@ -1072,14 +1072,16 @@ __mod_timer(struct timer_list *timer, unsigned long expires, unsigned int option
+ }
+
+ /**
+- * mod_timer_pending - modify a pending timer's timeout
+- * @timer: the pending timer to be modified
+- * @expires: new timeout in jiffies
++ * mod_timer_pending - Modify a pending timer's timeout
++ * @timer: The pending timer to be modified
++ * @expires: New absolute timeout in jiffies
+ *
+- * mod_timer_pending() is the same for pending timers as mod_timer(),
+- * but will not re-activate and modify already deleted timers.
++ * mod_timer_pending() is the same for pending timers as mod_timer(), but
++ * will not activate inactive timers.
+ *
+- * It is useful for unserialized use of timers.
++ * Return:
++ * * %0 - The timer was inactive and not modified
++ * * %1 - The timer was active and requeued to expire at @expires
+ */
+ int mod_timer_pending(struct timer_list *timer, unsigned long expires)
+ {
+@@ -1088,24 +1090,27 @@ int mod_timer_pending(struct timer_list *timer, unsigned long expires)
+ EXPORT_SYMBOL(mod_timer_pending);
+
+ /**
+- * mod_timer - modify a timer's timeout
+- * @timer: the timer to be modified
+- * @expires: new timeout in jiffies
+- *
+- * mod_timer() is a more efficient way to update the expire field of an
+- * active timer (if the timer is inactive it will be activated)
++ * mod_timer - Modify a timer's timeout
++ * @timer: The timer to be modified
++ * @expires: New absolute timeout in jiffies
+ *
+ * mod_timer(timer, expires) is equivalent to:
+ *
+ * del_timer(timer); timer->expires = expires; add_timer(timer);
+ *
++ * mod_timer() is more efficient than the above open coded sequence. In
++ * case that the timer is inactive, the del_timer() part is a NOP. The
++ * timer is in any case activated with the new expiry time @expires.
++ *
+ * Note that if there are multiple unserialized concurrent users of the
+ * same timer, then mod_timer() is the only safe way to modify the timeout,
+ * since add_timer() cannot modify an already running timer.
+ *
+- * The function returns whether it has modified a pending timer or not.
+- * (ie. mod_timer() of an inactive timer returns 0, mod_timer() of an
+- * active timer returns 1.)
++ * Return:
++ * * %0 - The timer was inactive and started
++ * * %1 - The timer was active and requeued to expire at @expires or
++ * the timer was active and not modified because @expires did
++ * not change the effective expiry time
+ */
+ int mod_timer(struct timer_list *timer, unsigned long expires)
+ {
+@@ -1116,11 +1121,18 @@ EXPORT_SYMBOL(mod_timer);
+ /**
+ * timer_reduce - Modify a timer's timeout if it would reduce the timeout
+ * @timer: The timer to be modified
+- * @expires: New timeout in jiffies
++ * @expires: New absolute timeout in jiffies
+ *
+ * timer_reduce() is very similar to mod_timer(), except that it will only
+- * modify a running timer if that would reduce the expiration time (it will
+- * start a timer that isn't running).
++ * modify an enqueued timer if that would reduce the expiration time. If
++ * @timer is not enqueued it starts the timer.
++ *
++ * Return:
++ * * %0 - The timer was inactive and started
++ * * %1 - The timer was active and requeued to expire at @expires or
++ * the timer was active and not modified because @expires
++ * did not change the effective expiry time such that the
++ * timer would expire earlier than already scheduled
+ */
+ int timer_reduce(struct timer_list *timer, unsigned long expires)
+ {
+@@ -1129,18 +1141,21 @@ int timer_reduce(struct timer_list *timer, unsigned long expires)
+ EXPORT_SYMBOL(timer_reduce);
+
+ /**
+- * add_timer - start a timer
+- * @timer: the timer to be added
++ * add_timer - Start a timer
++ * @timer: The timer to be started
+ *
+- * The kernel will do a ->function(@timer) callback from the
+- * timer interrupt at the ->expires point in the future. The
+- * current time is 'jiffies'.
++ * Start @timer to expire at @timer->expires in the future. @timer->expires
++ * is the absolute expiry time measured in 'jiffies'. When the timer expires
++ * timer->function(timer) will be invoked from soft interrupt context.
+ *
+- * The timer's ->expires, ->function fields must be set prior calling this
+- * function.
++ * The @timer->expires and @timer->function fields must be set prior
++ * to calling this function.
++ *
++ * If @timer->expires is already in the past @timer will be queued to
++ * expire at the next timer tick.
+ *
+- * Timers with an ->expires field in the past will be executed in the next
+- * timer tick.
++ * This can only operate on an inactive timer. Attempts to invoke this on
++ * an active timer are rejected with a warning.
+ */
+ void add_timer(struct timer_list *timer)
+ {
+@@ -1150,11 +1165,13 @@ void add_timer(struct timer_list *timer)
+ EXPORT_SYMBOL(add_timer);
+
+ /**
+- * add_timer_on - start a timer on a particular CPU
+- * @timer: the timer to be added
+- * @cpu: the CPU to start it on
++ * add_timer_on - Start a timer on a particular CPU
++ * @timer: The timer to be started
++ * @cpu: The CPU to start it on
++ *
++ * Same as add_timer() except that it starts the timer on the given CPU.
+ *
+- * This is not very scalable on SMP. Double adds are not possible.
++ * See add_timer() for further details.
+ */
+ void add_timer_on(struct timer_list *timer, int cpu)
+ {
+@@ -1189,15 +1206,18 @@ void add_timer_on(struct timer_list *timer, int cpu)
+ EXPORT_SYMBOL_GPL(add_timer_on);
+
+ /**
+- * del_timer - deactivate a timer.
+- * @timer: the timer to be deactivated
+- *
+- * del_timer() deactivates a timer - this works on both active and inactive
+- * timers.
+- *
+- * The function returns whether it has deactivated a pending timer or not.
+- * (ie. del_timer() of an inactive timer returns 0, del_timer() of an
+- * active timer returns 1.)
++ * del_timer - Deactivate a timer.
++ * @timer: The timer to be deactivated
++ *
++ * The function only deactivates a pending timer, but contrary to
++ * del_timer_sync() it does not take into account whether the timer's
++ * callback function is concurrently executed on a different CPU or not.
++ * It neither prevents rearming of the timer. If @timer can be rearmed
++ * concurrently then the return value of this function is meaningless.
++ *
++ * Return:
++ * * %0 - The timer was not pending
++ * * %1 - The timer was pending and deactivated
+ */
+ int del_timer(struct timer_list *timer)
+ {
+@@ -1219,10 +1239,19 @@ EXPORT_SYMBOL(del_timer);
+
+ /**
+ * try_to_del_timer_sync - Try to deactivate a timer
+- * @timer: timer to delete
++ * @timer: Timer to deactivate
++ *
++ * This function tries to deactivate a timer. On success the timer is not
++ * queued and the timer callback function is not running on any CPU.
+ *
+- * This function tries to deactivate a timer. Upon successful (ret >= 0)
+- * exit the timer is not queued and the handler is not running on any CPU.
++ * This function does not guarantee that the timer cannot be rearmed right
++ * after dropping the base lock. That needs to be prevented by the calling
++ * code if necessary.
++ *
++ * Return:
++ * * %0 - The timer was not pending
++ * * %1 - The timer was pending and deactivated
++ * * %-1 - The timer callback function is running on a different CPU
+ */
+ int try_to_del_timer_sync(struct timer_list *timer)
+ {
+@@ -1318,23 +1347,19 @@ static inline void del_timer_wait_running(struct timer_list *timer) { }
+
+ #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)
+ /**
+- * del_timer_sync - deactivate a timer and wait for the handler to finish.
+- * @timer: the timer to be deactivated
+- *
+- * This function only differs from del_timer() on SMP: besides deactivating
+- * the timer it also makes sure the handler has finished executing on other
+- * CPUs.
++ * del_timer_sync - Deactivate a timer and wait for the handler to finish.
++ * @timer: The timer to be deactivated
+ *
+ * Synchronization rules: Callers must prevent restarting of the timer,
+ * otherwise this function is meaningless. It must not be called from
+ * interrupt contexts unless the timer is an irqsafe one. The caller must
+- * not hold locks which would prevent completion of the timer's
+- * handler. The timer's handler must not call add_timer_on(). Upon exit the
+- * timer is not queued and the handler is not running on any CPU.
++ * not hold locks which would prevent completion of the timer's callback
++ * function. The timer's handler must not call add_timer_on(). Upon exit
++ * the timer is not queued and the handler is not running on any CPU.
+ *
+- * Note: For !irqsafe timers, you must not hold locks that are held in
+- * interrupt context while calling this function. Even if the lock has
+- * nothing to do with the timer in question. Here's why::
++ * For !irqsafe timers, the caller must not hold locks that are held in
++ * interrupt context. Even if the lock has nothing to do with the timer in
++ * question. Here's why::
+ *
+ * CPU0 CPU1
+ * ---- ----
+@@ -1348,10 +1373,17 @@ static inline void del_timer_wait_running(struct timer_list *timer) { }
+ * while (base->running_timer == mytimer);
+ *
+ * Now del_timer_sync() will never return and never release somelock.
+- * The interrupt on the other CPU is waiting to grab somelock but
+- * it has interrupted the softirq that CPU0 is waiting to finish.
++ * The interrupt on the other CPU is waiting to grab somelock but it has
++ * interrupted the softirq that CPU0 is waiting to finish.
++ *
++ * This function cannot guarantee that the timer is not rearmed again by
++ * some concurrent or preempting code, right after it dropped the base
++ * lock. If there is the possibility of a concurrent rearm then the return
++ * value of the function is meaningless.
+ *
+- * The function returns whether it has deactivated a pending timer or not.
++ * Return:
++ * * %0 - The timer was not pending
++ * * %1 - The timer was pending and deactivated
+ */
+ int del_timer_sync(struct timer_list *timer)
+ {
+--
+2.43.0
+
--- /dev/null
+From 3563faca31c6088cad3205a04c50be541bb30916 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Nov 2022 21:18:42 +0100
+Subject: timers: Use del_timer_sync() even on UP
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 168f6b6ffbeec0b9333f3582e4cf637300858db5 ]
+
+del_timer_sync() is assumed to be pointless on uniprocessor systems and can
+be mapped to del_timer() because in theory del_timer() can never be invoked
+while the timer callback function is executed.
+
+This is not entirely true because del_timer() can be invoked from interrupt
+context and therefore hit in the middle of a running timer callback.
+
+Contrary to that del_timer_sync() is not allowed to be invoked from
+interrupt context unless the affected timer is marked with TIMER_IRQSAFE.
+del_timer_sync() has proper checks in place to detect such a situation.
+
+Give up on the UP optimization and make del_timer_sync() unconditionally
+available.
+
+Co-developed-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
+Link: https://lore.kernel.org/all/20220407161745.7d6754b3@gandalf.local.home
+Link: https://lore.kernel.org/all/20221110064101.429013735@goodmis.org
+Link: https://lore.kernel.org/r/20221123201624.888306160@linutronix.de
+Stable-dep-of: 0f7352557a35 ("wifi: brcmfmac: Fix use-after-free bug in brcmf_cfg80211_detach")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/timer.h | 7 +------
+ kernel/time/timer.c | 2 --
+ 2 files changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/include/linux/timer.h b/include/linux/timer.h
+index 1e6650ed066d5..4de865f516154 100644
+--- a/include/linux/timer.h
++++ b/include/linux/timer.h
+@@ -182,12 +182,7 @@ extern int timer_reduce(struct timer_list *timer, unsigned long expires);
+ extern void add_timer(struct timer_list *timer);
+
+ extern int try_to_del_timer_sync(struct timer_list *timer);
+-
+-#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)
+- extern int del_timer_sync(struct timer_list *timer);
+-#else
+-# define del_timer_sync(t) del_timer(t)
+-#endif
++extern int del_timer_sync(struct timer_list *timer);
+
+ #define del_singleshot_timer_sync(t) del_timer_sync(t)
+
+diff --git a/kernel/time/timer.c b/kernel/time/timer.c
+index 973c66d9b3f90..0dfd1cacc4a00 100644
+--- a/kernel/time/timer.c
++++ b/kernel/time/timer.c
+@@ -1345,7 +1345,6 @@ static inline void timer_sync_wait_running(struct timer_base *base) { }
+ static inline void del_timer_wait_running(struct timer_list *timer) { }
+ #endif
+
+-#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)
+ /**
+ * del_timer_sync - Deactivate a timer and wait for the handler to finish.
+ * @timer: The timer to be deactivated
+@@ -1419,7 +1418,6 @@ int del_timer_sync(struct timer_list *timer)
+ return ret;
+ }
+ EXPORT_SYMBOL(del_timer_sync);
+-#endif
+
+ static void call_timer_fn(struct timer_list *timer,
+ void (*fn)(struct timer_list *),
+--
+2.43.0
+
--- /dev/null
+From 55d50d73a93c2057ec399d06f8ef78492b3a58ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jan 2024 07:37:02 +0100
+Subject: ubi: Check for too small LEB size in VTBL code
+
+From: Richard Weinberger <richard@nod.at>
+
+[ Upstream commit 68a24aba7c593eafa8fd00f2f76407b9b32b47a9 ]
+
+If the LEB size is smaller than a volume table record we cannot
+have volumes.
+In this case abort attaching.
+
+Cc: Chenyuan Yang <cy54@illinois.edu>
+Cc: stable@vger.kernel.org
+Fixes: 801c135ce73d ("UBI: Unsorted Block Images")
+Reported-by: Chenyuan Yang <cy54@illinois.edu>
+Closes: https://lore.kernel.org/linux-mtd/1433EB7A-FC89-47D6-8F47-23BE41B263B3@illinois.edu/
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/ubi/vtbl.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
+index 53d8ab54e1811..c891ee100dec4 100644
+--- a/drivers/mtd/ubi/vtbl.c
++++ b/drivers/mtd/ubi/vtbl.c
+@@ -791,6 +791,12 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_attach_info *ai)
+ * The number of supported volumes is limited by the eraseblock size
+ * and by the UBI_MAX_VOLUMES constant.
+ */
++
++ if (ubi->leb_size < UBI_VTBL_RECORD_SIZE) {
++ ubi_err(ubi, "LEB size too small for a volume record");
++ return -EINVAL;
++ }
++
+ ubi->vtbl_slots = ubi->leb_size / UBI_VTBL_RECORD_SIZE;
+ if (ubi->vtbl_slots > UBI_MAX_VOLUMES)
+ ubi->vtbl_slots = UBI_MAX_VOLUMES;
+--
+2.43.0
+
--- /dev/null
+From a9c278c72ea7a7be518a43f3b4b4cd9692348490 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Feb 2024 10:49:03 +0800
+Subject: ubi: correct the calculation of fastmap size
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+[ Upstream commit 7f174ae4f39e8475adcc09d26c5a43394689ad6c ]
+
+Now that the calculation of fastmap size in ubi_calc_fm_size() is
+incorrect since it miss each user volume's ubi_fm_eba structure and the
+Internal UBI volume info. Let's correct the calculation.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/ubi/fastmap.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
+index 6e95c4b1473e6..8081fc760d34f 100644
+--- a/drivers/mtd/ubi/fastmap.c
++++ b/drivers/mtd/ubi/fastmap.c
+@@ -86,9 +86,10 @@ size_t ubi_calc_fm_size(struct ubi_device *ubi)
+ sizeof(struct ubi_fm_scan_pool) +
+ sizeof(struct ubi_fm_scan_pool) +
+ (ubi->peb_count * sizeof(struct ubi_fm_ec)) +
+- (sizeof(struct ubi_fm_eba) +
+- (ubi->peb_count * sizeof(__be32))) +
+- sizeof(struct ubi_fm_volhdr) * UBI_MAX_VOLUMES;
++ ((sizeof(struct ubi_fm_eba) +
++ sizeof(struct ubi_fm_volhdr)) *
++ (UBI_MAX_VOLUMES + UBI_INT_VOL_COUNT)) +
++ (ubi->peb_count * sizeof(__be32));
+ return roundup(size, ubi->leb_size);
+ }
+
+--
+2.43.0
+
--- /dev/null
+From 045fbd81ef3f2f279e03d8beebe98a02d6166485 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Jan 2024 17:52:44 +0000
+Subject: ubifs: Set page uptodate in the correct place
+
+From: Matthew Wilcox (Oracle) <willy@infradead.org>
+
+[ Upstream commit 723012cab779eee8228376754e22c6594229bf8f ]
+
+Page cache reads are lockless, so setting the freshly allocated page
+uptodate before we've overwritten it with the data it's supposed to have
+in it will allow a simultaneous reader to see old data. Move the call
+to SetPageUptodate into ubifs_write_end(), which is after we copied the
+new data into the page.
+
+Fixes: 1e51764a3c2a ("UBIFS: add new flash file system")
+Cc: stable@vger.kernel.org
+Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ubifs/file.c | 13 ++++---------
+ 1 file changed, 4 insertions(+), 9 deletions(-)
+
+diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
+index 4d3a5cb6e9b03..ebad140f8d056 100644
+--- a/fs/ubifs/file.c
++++ b/fs/ubifs/file.c
+@@ -262,9 +262,6 @@ static int write_begin_slow(struct address_space *mapping,
+ return err;
+ }
+ }
+-
+- SetPageUptodate(page);
+- ClearPageError(page);
+ }
+
+ if (PagePrivate(page))
+@@ -463,9 +460,6 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
+ return err;
+ }
+ }
+-
+- SetPageUptodate(page);
+- ClearPageError(page);
+ }
+
+ err = allocate_budget(c, page, ui, appending);
+@@ -475,10 +469,8 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
+ * If we skipped reading the page because we were going to
+ * write all of it, then it is not up to date.
+ */
+- if (skipped_read) {
++ if (skipped_read)
+ ClearPageChecked(page);
+- ClearPageUptodate(page);
+- }
+ /*
+ * Budgeting failed which means it would have to force
+ * write-back but didn't, because we set the @fast flag in the
+@@ -569,6 +561,9 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping,
+ goto out;
+ }
+
++ if (len == PAGE_SIZE)
++ SetPageUptodate(page);
++
+ if (!PagePrivate(page)) {
+ SetPagePrivate(page);
+ atomic_long_inc(&c->dirty_pg_cnt);
+--
+2.43.0
+
--- /dev/null
+From 2beb4f71b19ed8d4c9c875ff46e41339d238e40f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Feb 2024 21:53:29 +0000
+Subject: USB: serial: add device ID for VeriFone adapter
+
+From: Cameron Williams <cang1@live.co.uk>
+
+[ Upstream commit cda704809797a8a86284f9df3eef5e62ec8a3175 ]
+
+Add device ID for a (probably fake) CP2102 UART device.
+
+lsusb -v output:
+
+Device Descriptor:
+ bLength 18
+ bDescriptorType 1
+ bcdUSB 1.10
+ bDeviceClass 0 [unknown]
+ bDeviceSubClass 0 [unknown]
+ bDeviceProtocol 0
+ bMaxPacketSize0 64
+ idVendor 0x11ca VeriFone Inc
+ idProduct 0x0212 Verifone USB to Printer
+ bcdDevice 1.00
+ iManufacturer 1 Silicon Labs
+ iProduct 2 Verifone USB to Printer
+ iSerial 3 0001
+ bNumConfigurations 1
+ Configuration Descriptor:
+ bLength 9
+ bDescriptorType 2
+ wTotalLength 0x0020
+ bNumInterfaces 1
+ bConfigurationValue 1
+ iConfiguration 0
+ bmAttributes 0x80
+ (Bus Powered)
+ MaxPower 100mA
+ Interface Descriptor:
+ bLength 9
+ bDescriptorType 4
+ bInterfaceNumber 0
+ bAlternateSetting 0
+ bNumEndpoints 2
+ bInterfaceClass 255 Vendor Specific Class
+ bInterfaceSubClass 0 [unknown]
+ bInterfaceProtocol 0
+ iInterface 2 Verifone USB to Printer
+ Endpoint Descriptor:
+ bLength 7
+ bDescriptorType 5
+ bEndpointAddress 0x81 EP 1 IN
+ bmAttributes 2
+ Transfer Type Bulk
+ Synch Type None
+ Usage Type Data
+ wMaxPacketSize 0x0040 1x 64 bytes
+ bInterval 0
+ Endpoint Descriptor:
+ bLength 7
+ bDescriptorType 5
+ bEndpointAddress 0x01 EP 1 OUT
+ bmAttributes 2
+ Transfer Type Bulk
+ Synch Type None
+ Usage Type Data
+ wMaxPacketSize 0x0040 1x 64 bytes
+ bInterval 0
+Device Status: 0x0000
+ (Bus Powered)
+
+Signed-off-by: Cameron Williams <cang1@live.co.uk>
+Cc: stable@vger.kernel.org
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/serial/cp210x.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index 1724cade102e1..015dcaf58047c 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -178,6 +178,7 @@ static const struct usb_device_id id_table[] = {
+ { USB_DEVICE(0x10C4, 0xF004) }, /* Elan Digital Systems USBcount50 */
+ { USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */
+ { USB_DEVICE(0x10CE, 0xEA6A) }, /* Silicon Labs MobiData GPRS USB Modem 100EU */
++ { USB_DEVICE(0x11CA, 0x0212) }, /* Verifone USB to Printer (UART, CP2102) */
+ { USB_DEVICE(0x12B8, 0xEC60) }, /* Link G4 ECU */
+ { USB_DEVICE(0x12B8, 0xEC62) }, /* Link G4+ ECU */
+ { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
+--
+2.43.0
+
--- /dev/null
+From 8144c53c10b4dfcc73f3cf0aa598e9699b38b4a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Feb 2024 11:47:29 +0100
+Subject: USB: serial: cp210x: add ID for MGP Instruments PDS100
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christian Häggström <christian.haggstrom@orexplore.com>
+
+[ Upstream commit a0d9d868491a362d421521499d98308c8e3a0398 ]
+
+The radiation meter has the text MGP Instruments PDS-100G or PDS-100GN
+produced by Mirion Technologies. Tested by forcing the driver
+association with
+
+ echo 10c4 863c > /sys/bus/usb-serial/drivers/cp210x/new_id
+
+and then setting the serial port in 115200 8N1 mode. The device
+announces ID_USB_VENDOR_ENC=Silicon\x20Labs and ID_USB_MODEL_ENC=PDS100
+
+Signed-off-by: Christian Häggström <christian.haggstrom@orexplore.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/serial/cp210x.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index 015dcaf58047c..88659a75f30f9 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -145,6 +145,7 @@ static const struct usb_device_id id_table[] = {
+ { USB_DEVICE(0x10C4, 0x85EA) }, /* AC-Services IBUS-IF */
+ { USB_DEVICE(0x10C4, 0x85EB) }, /* AC-Services CIS-IBUS */
+ { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */
++ { USB_DEVICE(0x10C4, 0x863C) }, /* MGP Instruments PDS100 */
+ { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */
+ { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */
+ { USB_DEVICE(0x10C4, 0x87ED) }, /* IMST USB-Stick for Smart Meter */
+--
+2.43.0
+
--- /dev/null
+From ff8fc7cda24e8f4affe141aacde2fb3cf4657d56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 08:46:14 +0900
+Subject: USB: serial: cp210x: add pid/vid for TDK NC0110013M and MM0110113M
+
+From: Toru Katagiri <Toru.Katagiri@tdk.com>
+
+[ Upstream commit b1a8da9ff1395c4879b4bd41e55733d944f3d613 ]
+
+TDK NC0110013M and MM0110113M have custom USB IDs for CP210x,
+so we need to add them to the driver.
+
+Signed-off-by: Toru Katagiri <Toru.Katagiri@tdk.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/serial/cp210x.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index 88659a75f30f9..5353fa7e59696 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -57,6 +57,8 @@ static const struct usb_device_id id_table[] = {
+ { USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */
+ { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */
+ { USB_DEVICE(0x0489, 0xE003) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */
++ { USB_DEVICE(0x04BF, 0x1301) }, /* TDK Corporation NC0110013M - Network Controller */
++ { USB_DEVICE(0x04BF, 0x1303) }, /* TDK Corporation MM0110113M - i3 Micro Module */
+ { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */
+ { USB_DEVICE(0x0846, 0x1100) }, /* NetGear Managed Switch M4100 series, M5300 series, M7100 series */
+ { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */
+--
+2.43.0
+
--- /dev/null
+From 78d6e0623c617b7032cb52fd29ae76d920bdac1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 11 Feb 2024 15:42:46 +0100
+Subject: USB: serial: ftdi_sio: add support for GMC Z216C Adapter IR-USB
+
+From: Daniel Vogelbacher <daniel@chaospixel.com>
+
+[ Upstream commit 3fb7bc4f3a98c48981318b87cf553c5f115fd5ca ]
+
+The GMC IR-USB adapter cable utilizes a FTDI FT232R chip.
+
+Add VID/PID for this adapter so it can be used as serial device via
+ftdi_sio.
+
+Signed-off-by: Daniel Vogelbacher <daniel@chaospixel.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/serial/ftdi_sio.c | 2 ++
+ drivers/usb/serial/ftdi_sio_ids.h | 6 ++++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index c97923858fce6..bfb0be4e70d5e 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -1055,6 +1055,8 @@ static const struct usb_device_id id_table_combined[] = {
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_UNBUF_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
++ /* GMC devices */
++ { USB_DEVICE(GMC_VID, GMC_Z216C_PID) },
+ { } /* Terminating entry */
+ };
+
+diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
+index 9a0f9fc991246..b2aec1106678a 100644
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -1599,3 +1599,9 @@
+ #define UBLOX_VID 0x1546
+ #define UBLOX_C099F9P_ZED_PID 0x0502
+ #define UBLOX_C099F9P_ODIN_PID 0x0503
++
++/*
++ * GMC devices
++ */
++#define GMC_VID 0x1cd7
++#define GMC_Z216C_PID 0x0217 /* GMC Z216C Adapter IR-USB */
+--
+2.43.0
+
--- /dev/null
+From d052ea1549170db9de28018e5f9c18c65a452d3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Jan 2024 18:49:17 +0100
+Subject: USB: serial: option: add MeiG Smart SLM320 product
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Aurélien Jacobs <aurel@gnuage.org>
+
+[ Upstream commit 46809c51565b83881aede6cdf3b0d25254966a41 ]
+
+Update the USB serial option driver to support MeiG Smart SLM320.
+
+ID 2dee:4d41 UNISOC UNISOC-8910
+
+T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 9 Spd=480 MxCh= 0
+D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
+P: Vendor=2dee ProdID=4d41 Rev=00.00
+S: Manufacturer=UNISOC
+S: Product=UNISOC-8910
+C: #Ifs= 8 Cfg#= 1 Atr=e0 MxPwr=400mA
+I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+I: If#= 7 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
+E: Ad=08(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+
+Tested successfully a PPP LTE connection using If#= 0.
+Not sure of the purpose of every other serial interfaces.
+
+Signed-off-by: Aurélien Jacobs <aurel@gnuage.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/serial/option.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index 406cfd5ad9f48..17c3044c2d26a 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -613,6 +613,11 @@ static void option_instat_callback(struct urb *urb);
+ /* Luat Air72*U series based on UNISOC UIS8910 uses UNISOC's vendor ID */
+ #define LUAT_PRODUCT_AIR720U 0x4e00
+
++/* MeiG Smart Technology products */
++#define MEIGSMART_VENDOR_ID 0x2dee
++/* MeiG Smart SLM320 based on UNISOC UIS8910 */
++#define MEIGSMART_PRODUCT_SLM320 0x4d41
++
+ /* Device flags */
+
+ /* Highest interface number which can be used with NCTRL() and RSVD() */
+@@ -2282,6 +2287,7 @@ static const struct usb_device_id option_ids[] = {
+ { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) },
+ { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) },
+ { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) },
++ { USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) },
+ { } /* Terminating entry */
+ };
+ MODULE_DEVICE_TABLE(usb, option_ids);
+--
+2.43.0
+
--- /dev/null
+From e5ea57bd9d759bb9bdd1fceb8cbd54cba0320bfd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Mar 2024 16:05:26 -0700
+Subject: vfio/platform: Disable virqfds on cleanup
+
+From: Alex Williamson <alex.williamson@redhat.com>
+
+[ Upstream commit fcdc0d3d40bc26c105acf8467f7d9018970944ae ]
+
+irqfds for mask and unmask that are not specifically disabled by the
+user are leaked. Remove any irqfds during cleanup
+
+Cc: Eric Auger <eric.auger@redhat.com>
+Cc: <stable@vger.kernel.org>
+Fixes: a7fa7c77cf15 ("vfio/platform: implement IRQ masking/unmasking via an eventfd")
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Reviewed-by: Eric Auger <eric.auger@redhat.com>
+Link: https://lore.kernel.org/r/20240308230557.805580-6-alex.williamson@redhat.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vfio/platform/vfio_platform_irq.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
+index c5b09ec0a3c98..f2893f2fcaabd 100644
+--- a/drivers/vfio/platform/vfio_platform_irq.c
++++ b/drivers/vfio/platform/vfio_platform_irq.c
+@@ -321,8 +321,11 @@ void vfio_platform_irq_cleanup(struct vfio_platform_device *vdev)
+ {
+ int i;
+
+- for (i = 0; i < vdev->num_irqs; i++)
++ for (i = 0; i < vdev->num_irqs; i++) {
++ vfio_virqfd_disable(&vdev->irqs[i].mask);
++ vfio_virqfd_disable(&vdev->irqs[i].unmask);
+ vfio_set_trigger(vdev, i, -1, NULL);
++ }
+
+ vdev->num_irqs = 0;
+ kfree(vdev->irqs);
+--
+2.43.0
+
--- /dev/null
+From 0ae8d3f3edc36b02b54ff1ca83077e8d790fd287 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jan 2024 08:25:04 +0100
+Subject: wifi: brcmfmac: Fix use-after-free bug in brcmf_cfg80211_detach
+
+From: Zheng Wang <zyytlz.wz@163.com>
+
+[ Upstream commit 0f7352557a35ab7888bc7831411ec8a3cbe20d78 ]
+
+This is the candidate patch of CVE-2023-47233 :
+https://nvd.nist.gov/vuln/detail/CVE-2023-47233
+
+In brcm80211 driver,it starts with the following invoking chain
+to start init a timeout worker:
+
+->brcmf_usb_probe
+ ->brcmf_usb_probe_cb
+ ->brcmf_attach
+ ->brcmf_bus_started
+ ->brcmf_cfg80211_attach
+ ->wl_init_priv
+ ->brcmf_init_escan
+ ->INIT_WORK(&cfg->escan_timeout_work,
+ brcmf_cfg80211_escan_timeout_worker);
+
+If we disconnect the USB by hotplug, it will call
+brcmf_usb_disconnect to make cleanup. The invoking chain is :
+
+brcmf_usb_disconnect
+ ->brcmf_usb_disconnect_cb
+ ->brcmf_detach
+ ->brcmf_cfg80211_detach
+ ->kfree(cfg);
+
+While the timeout woker may still be running. This will cause
+a use-after-free bug on cfg in brcmf_cfg80211_escan_timeout_worker.
+
+Fix it by deleting the timer and canceling the worker in
+brcmf_cfg80211_detach.
+
+Fixes: e756af5b30b0 ("brcmfmac: add e-scan support.")
+Signed-off-by: Zheng Wang <zyytlz.wz@163.com>
+Cc: stable@vger.kernel.org
+[arend.vanspriel@broadcom.com: keep timer delete as is and cancel work just before free]
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20240107072504.392713-1-arend.vanspriel@broadcom.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+index b7ceea0b3204d..668c8897c1095 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -710,8 +710,7 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
+ scan_request = cfg->scan_request;
+ cfg->scan_request = NULL;
+
+- if (timer_pending(&cfg->escan_timeout))
+- del_timer_sync(&cfg->escan_timeout);
++ timer_delete_sync(&cfg->escan_timeout);
+
+ if (fw_abort) {
+ /* Do a scan abort to stop the driver's scan engine */
+@@ -7240,6 +7239,7 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
+ brcmf_btcoex_detach(cfg);
+ wiphy_unregister(cfg->wiphy);
+ wl_deinit_priv(cfg);
++ cancel_work_sync(&cfg->escan_timeout_work);
+ brcmf_free_wiphy(cfg->wiphy);
+ kfree(cfg);
+ }
+--
+2.43.0
+
--- /dev/null
+From bbe48e9f7d1a9ae4b8ebf7bb04e9370f2b7aeea4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Mar 2024 22:42:27 +0100
+Subject: x86/CPU/AMD: Update the Zenbleed microcode revisions
+
+From: Borislav Petkov (AMD) <bp@alien8.de>
+
+[ Upstream commit 5c84b051bd4e777cf37aaff983277e58c99618d5 ]
+
+Update them to the correct revision numbers.
+
+Fixes: 522b1d69219d ("x86/cpu/amd: Add a Zenbleed fix")
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Cc: <stable@kernel.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/amd.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
+index 4e84203fc067d..533451498c8f8 100644
+--- a/arch/x86/kernel/cpu/amd.c
++++ b/arch/x86/kernel/cpu/amd.c
+@@ -998,11 +998,11 @@ static bool cpu_has_zenbleed_microcode(void)
+ u32 good_rev = 0;
+
+ switch (boot_cpu_data.x86_model) {
+- case 0x30 ... 0x3f: good_rev = 0x0830107a; break;
+- case 0x60 ... 0x67: good_rev = 0x0860010b; break;
+- case 0x68 ... 0x6f: good_rev = 0x08608105; break;
+- case 0x70 ... 0x7f: good_rev = 0x08701032; break;
+- case 0xa0 ... 0xaf: good_rev = 0x08a00008; break;
++ case 0x30 ... 0x3f: good_rev = 0x0830107b; break;
++ case 0x60 ... 0x67: good_rev = 0x0860010c; break;
++ case 0x68 ... 0x6f: good_rev = 0x08608107; break;
++ case 0x70 ... 0x7f: good_rev = 0x08701033; break;
++ case 0xa0 ... 0xaf: good_rev = 0x08a00009; break;
+
+ default:
+ return false;
+--
+2.43.0
+