]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.4
authorSasha Levin <sashal@kernel.org>
Wed, 27 Mar 2024 11:08:43 +0000 (07:08 -0400)
committerSasha Levin <sashal@kernel.org>
Wed, 27 Mar 2024 11:08:43 +0000 (07:08 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
77 files changed:
queue-5.4/ahci-asm1064-asm1166-don-t-limit-reported-ports.patch [new file with mode: 0644]
queue-5.4/ahci-asm1064-correct-count-of-reported-ports.patch [new file with mode: 0644]
queue-5.4/arm-dts-marvell-fix-maxium-maxim-typo-in-brownstone-.patch [new file with mode: 0644]
queue-5.4/arm-dts-mmp2-brownstone-don-t-redeclare-phandle-refe.patch [new file with mode: 0644]
queue-5.4/btrfs-fix-off-by-one-chunk-length-calculation-at-con.patch [new file with mode: 0644]
queue-5.4/clk-qcom-gcc-ipq8074-fix-terminating-of-frequency-ta.patch [new file with mode: 0644]
queue-5.4/clk-qcom-gcc-sdm845-add-soft-dependency-on-rpmhpd.patch [new file with mode: 0644]
queue-5.4/clk-qcom-mmcc-apq8084-fix-terminating-of-frequency-t.patch [new file with mode: 0644]
queue-5.4/clk-qcom-mmcc-msm8974-fix-terminating-of-frequency-t.patch [new file with mode: 0644]
queue-5.4/crypto-qat-fix-double-free-during-reset.patch [new file with mode: 0644]
queue-5.4/crypto-qat-resolve-race-condition-during-aer-recover.patch [new file with mode: 0644]
queue-5.4/dm-raid-fix-lockdep-waring-in-pers-hot_add_disk.patch [new file with mode: 0644]
queue-5.4/dm-snapshot-fix-lockup-in-dm_exception_table_exit.patch [new file with mode: 0644]
queue-5.4/drm-exynos-do-not-return-negative-values-from-.get_m.patch [new file with mode: 0644]
queue-5.4/drm-imx-ipuv3-do-not-return-negative-values-from-.ge.patch [new file with mode: 0644]
queue-5.4/drm-vc4-hdmi-do-not-return-negative-values-from-.get.patch [new file with mode: 0644]
queue-5.4/ext4-correct-best-extent-lstart-adjustment-logic.patch [new file with mode: 0644]
queue-5.4/ext4-fix-corruption-during-on-line-resize.patch [new file with mode: 0644]
queue-5.4/fat-fix-uninitialized-field-in-nostale-filehandles.patch [new file with mode: 0644]
queue-5.4/firmware-meson_sm-rework-driver-as-a-proper-platform.patch [new file with mode: 0644]
queue-5.4/fuse-don-t-unhash-root.patch [new file with mode: 0644]
queue-5.4/fuse-drop-fuse_conn-parameter-where-possible.patch [new file with mode: 0644]
queue-5.4/fuse-store-fuse_conn-in-fuse_req.patch [new file with mode: 0644]
queue-5.4/hwmon-amc6821-add-of_match-table.patch [new file with mode: 0644]
queue-5.4/kbuild-move-wenum-compare-conditional-enum-conversio.patch [new file with mode: 0644]
queue-5.4/kvm-always-flush-async-pf-workqueue-when-vcpu-is-bei.patch [new file with mode: 0644]
queue-5.4/media-staging-ipu3-imgu-set-fields-before-media_enti.patch [new file with mode: 0644]
queue-5.4/media-xc4000-fix-atomicity-violation-in-xc4000_get_f.patch [new file with mode: 0644]
queue-5.4/memtest-use-read-write-_once-in-memory-scanning.patch [new file with mode: 0644]
queue-5.4/mmc-core-fix-switch-on-gp3-partition.patch [new file with mode: 0644]
queue-5.4/mmc-tmio-avoid-concurrent-runs-of-mmc_request_done.patch [new file with mode: 0644]
queue-5.4/mtd-rawnand-meson-fix-scrambling-mode-value-in-comma.patch [new file with mode: 0644]
queue-5.4/nilfs2-fix-failure-to-detect-dat-corruption-in-btree.patch [new file with mode: 0644]
queue-5.4/nilfs2-prevent-kernel-bug-at-submit_bh_wbc.patch [new file with mode: 0644]
queue-5.4/nilfs2-use-a-more-common-logging-style.patch [new file with mode: 0644]
queue-5.4/nvmem-meson-efuse-fix-function-pointer-type-mismatch.patch [new file with mode: 0644]
queue-5.4/parisc-do-not-hardcode-registers-in-checksum-functio.patch [new file with mode: 0644]
queue-5.4/parisc-fix-csum_ipv6_magic-on-32-bit-systems.patch [new file with mode: 0644]
queue-5.4/parisc-fix-csum_ipv6_magic-on-64-bit-systems.patch [new file with mode: 0644]
queue-5.4/parisc-fix-ip_fast_csum.patch [new file with mode: 0644]
queue-5.4/parisc-strip-upper-32-bit-of-sum-in-csum_ipv6_magic-.patch [new file with mode: 0644]
queue-5.4/pci-drop-pci_device_remove-test-of-pci_dev-driver.patch [new file with mode: 0644]
queue-5.4/pci-pm-drain-runtime-idle-callbacks-before-driver-re.patch [new file with mode: 0644]
queue-5.4/pm-sleep-wakeirq-fix-wake-irq-warning-in-system-susp.patch [new file with mode: 0644]
queue-5.4/pm-suspend-set-mem_sleep_current-during-kernel-comma.patch [new file with mode: 0644]
queue-5.4/powerpc-fsl-fix-mfpmr-build-errors-with-newer-binuti.patch [new file with mode: 0644]
queue-5.4/revert-revert-md-raid5-wait-for-md_sb_change_pending.patch [new file with mode: 0644]
queue-5.4/ring-buffer-fix-full_waiters_pending-in-poll.patch [new file with mode: 0644]
queue-5.4/ring-buffer-fix-resetting-of-shortest_full.patch [new file with mode: 0644]
queue-5.4/s390-zcrypt-fix-reference-counting-on-zcrypt-card-ob.patch [new file with mode: 0644]
queue-5.4/selftests-mqueue-set-timeout-to-180-seconds.patch [new file with mode: 0644]
queue-5.4/serial-max310x-fix-null-pointer-dereference-in-i2c-i.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/slimbus-core-remove-usage-of-the-deprecated-ida_simp.patch [new file with mode: 0644]
queue-5.4/smack-handle-smack64transmute-in-smack_inode_setsecu.patch [new file with mode: 0644]
queue-5.4/smack-set-smack64transmute-only-for-dirs-in-smack_in.patch [new file with mode: 0644]
queue-5.4/soc-fsl-qbman-add-cgr-update-function.patch [new file with mode: 0644]
queue-5.4/soc-fsl-qbman-add-helper-for-sanity-checking-cgr-ops.patch [new file with mode: 0644]
queue-5.4/soc-fsl-qbman-always-disable-interrupts-when-taking-.patch [new file with mode: 0644]
queue-5.4/soc-fsl-qbman-use-raw-spinlock-for-cgr_lock.patch [new file with mode: 0644]
queue-5.4/sparc-vdso-fix-return-value-of-__setup-handler.patch [new file with mode: 0644]
queue-5.4/sparc64-nmi-watchdog-fix-return-value-of-__setup-han.patch [new file with mode: 0644]
queue-5.4/speakup-fix-8bit-characters-from-direct-synth.patch [new file with mode: 0644]
queue-5.4/timers-rename-del_timer_sync-to-timer_delete_sync.patch [new file with mode: 0644]
queue-5.4/timers-update-kernel-doc-for-various-functions.patch [new file with mode: 0644]
queue-5.4/timers-use-del_timer_sync-even-on-up.patch [new file with mode: 0644]
queue-5.4/ubi-check-for-too-small-leb-size-in-vtbl-code.patch [new file with mode: 0644]
queue-5.4/ubi-correct-the-calculation-of-fastmap-size.patch [new file with mode: 0644]
queue-5.4/ubifs-set-page-uptodate-in-the-correct-place.patch [new file with mode: 0644]
queue-5.4/usb-serial-add-device-id-for-verifone-adapter.patch [new file with mode: 0644]
queue-5.4/usb-serial-cp210x-add-id-for-mgp-instruments-pds100.patch [new file with mode: 0644]
queue-5.4/usb-serial-cp210x-add-pid-vid-for-tdk-nc0110013m-and.patch [new file with mode: 0644]
queue-5.4/usb-serial-ftdi_sio-add-support-for-gmc-z216c-adapte.patch [new file with mode: 0644]
queue-5.4/usb-serial-option-add-meig-smart-slm320-product.patch [new file with mode: 0644]
queue-5.4/vfio-platform-disable-virqfds-on-cleanup.patch [new file with mode: 0644]
queue-5.4/wifi-brcmfmac-fix-use-after-free-bug-in-brcmf_cfg802.patch [new file with mode: 0644]
queue-5.4/x86-cpu-amd-update-the-zenbleed-microcode-revisions.patch [new file with mode: 0644]

diff --git a/queue-5.4/ahci-asm1064-asm1166-don-t-limit-reported-ports.patch b/queue-5.4/ahci-asm1064-asm1166-don-t-limit-reported-ports.patch
new file mode 100644 (file)
index 0000000..2062910
--- /dev/null
@@ -0,0 +1,89 @@
+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
+
diff --git a/queue-5.4/ahci-asm1064-correct-count-of-reported-ports.patch b/queue-5.4/ahci-asm1064-correct-count-of-reported-ports.patch
new file mode 100644 (file)
index 0000000..cf86fe7
--- /dev/null
@@ -0,0 +1,60 @@
+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
+
diff --git a/queue-5.4/arm-dts-marvell-fix-maxium-maxim-typo-in-brownstone-.patch b/queue-5.4/arm-dts-marvell-fix-maxium-maxim-typo-in-brownstone-.patch
new file mode 100644 (file)
index 0000000..a675b37
--- /dev/null
@@ -0,0 +1,46 @@
+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
+
diff --git a/queue-5.4/arm-dts-mmp2-brownstone-don-t-redeclare-phandle-refe.patch b/queue-5.4/arm-dts-mmp2-brownstone-don-t-redeclare-phandle-refe.patch
new file mode 100644 (file)
index 0000000..9f22c2a
--- /dev/null
@@ -0,0 +1,371 @@
+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
+
diff --git a/queue-5.4/btrfs-fix-off-by-one-chunk-length-calculation-at-con.patch b/queue-5.4/btrfs-fix-off-by-one-chunk-length-calculation-at-con.patch
new file mode 100644 (file)
index 0000000..f0ce05b
--- /dev/null
@@ -0,0 +1,48 @@
+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
+
diff --git a/queue-5.4/clk-qcom-gcc-ipq8074-fix-terminating-of-frequency-ta.patch b/queue-5.4/clk-qcom-gcc-ipq8074-fix-terminating-of-frequency-ta.patch
new file mode 100644 (file)
index 0000000..8464f92
--- /dev/null
@@ -0,0 +1,51 @@
+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
+
diff --git a/queue-5.4/clk-qcom-gcc-sdm845-add-soft-dependency-on-rpmhpd.patch b/queue-5.4/clk-qcom-gcc-sdm845-add-soft-dependency-on-rpmhpd.patch
new file mode 100644 (file)
index 0000000..70bac13
--- /dev/null
@@ -0,0 +1,40 @@
+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
+
diff --git a/queue-5.4/clk-qcom-mmcc-apq8084-fix-terminating-of-frequency-t.patch b/queue-5.4/clk-qcom-mmcc-apq8084-fix-terminating-of-frequency-t.patch
new file mode 100644 (file)
index 0000000..05cc81d
--- /dev/null
@@ -0,0 +1,51 @@
+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
+
diff --git a/queue-5.4/clk-qcom-mmcc-msm8974-fix-terminating-of-frequency-t.patch b/queue-5.4/clk-qcom-mmcc-msm8974-fix-terminating-of-frequency-t.patch
new file mode 100644 (file)
index 0000000..8fea95c
--- /dev/null
@@ -0,0 +1,51 @@
+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
+
diff --git a/queue-5.4/crypto-qat-fix-double-free-during-reset.patch b/queue-5.4/crypto-qat-fix-double-free-during-reset.patch
new file mode 100644 (file)
index 0000000..336b1b8
--- /dev/null
@@ -0,0 +1,42 @@
+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
+
diff --git a/queue-5.4/crypto-qat-resolve-race-condition-during-aer-recover.patch b/queue-5.4/crypto-qat-resolve-race-condition-during-aer-recover.patch
new file mode 100644 (file)
index 0000000..c15feda
--- /dev/null
@@ -0,0 +1,92 @@
+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
+
diff --git a/queue-5.4/dm-raid-fix-lockdep-waring-in-pers-hot_add_disk.patch b/queue-5.4/dm-raid-fix-lockdep-waring-in-pers-hot_add_disk.patch
new file mode 100644 (file)
index 0000000..3b3702d
--- /dev/null
@@ -0,0 +1,49 @@
+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
+
diff --git a/queue-5.4/dm-snapshot-fix-lockup-in-dm_exception_table_exit.patch b/queue-5.4/dm-snapshot-fix-lockup-in-dm_exception_table_exit.patch
new file mode 100644 (file)
index 0000000..796dd60
--- /dev/null
@@ -0,0 +1,40 @@
+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
+
diff --git a/queue-5.4/drm-exynos-do-not-return-negative-values-from-.get_m.patch b/queue-5.4/drm-exynos-do-not-return-negative-values-from-.get_m.patch
new file mode 100644 (file)
index 0000000..7e4c652
--- /dev/null
@@ -0,0 +1,67 @@
+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
+
diff --git a/queue-5.4/drm-imx-ipuv3-do-not-return-negative-values-from-.ge.patch b/queue-5.4/drm-imx-ipuv3-do-not-return-negative-values-from-.ge.patch
new file mode 100644 (file)
index 0000000..f82c3fb
--- /dev/null
@@ -0,0 +1,47 @@
+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
+
diff --git a/queue-5.4/drm-vc4-hdmi-do-not-return-negative-values-from-.get.patch b/queue-5.4/drm-vc4-hdmi-do-not-return-negative-values-from-.get.patch
new file mode 100644 (file)
index 0000000..14bcd78
--- /dev/null
@@ -0,0 +1,39 @@
+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
+
diff --git a/queue-5.4/ext4-correct-best-extent-lstart-adjustment-logic.patch b/queue-5.4/ext4-correct-best-extent-lstart-adjustment-logic.patch
new file mode 100644 (file)
index 0000000..8da6e5c
--- /dev/null
@@ -0,0 +1,95 @@
+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
+
diff --git a/queue-5.4/ext4-fix-corruption-during-on-line-resize.patch b/queue-5.4/ext4-fix-corruption-during-on-line-resize.patch
new file mode 100644 (file)
index 0000000..55db211
--- /dev/null
@@ -0,0 +1,79 @@
+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
+
diff --git a/queue-5.4/fat-fix-uninitialized-field-in-nostale-filehandles.patch b/queue-5.4/fat-fix-uninitialized-field-in-nostale-filehandles.patch
new file mode 100644 (file)
index 0000000..634060f
--- /dev/null
@@ -0,0 +1,49 @@
+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
+
diff --git a/queue-5.4/firmware-meson_sm-rework-driver-as-a-proper-platform.patch b/queue-5.4/firmware-meson_sm-rework-driver-as-a-proper-platform.patch
new file mode 100644 (file)
index 0000000..4ee2f9a
--- /dev/null
@@ -0,0 +1,353 @@
+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
+
diff --git a/queue-5.4/fuse-don-t-unhash-root.patch b/queue-5.4/fuse-don-t-unhash-root.patch
new file mode 100644 (file)
index 0000000..25b1dfc
--- /dev/null
@@ -0,0 +1,54 @@
+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
+
diff --git a/queue-5.4/fuse-drop-fuse_conn-parameter-where-possible.patch b/queue-5.4/fuse-drop-fuse_conn-parameter-where-possible.patch
new file mode 100644 (file)
index 0000000..c838bcb
--- /dev/null
@@ -0,0 +1,342 @@
+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
+
diff --git a/queue-5.4/fuse-store-fuse_conn-in-fuse_req.patch b/queue-5.4/fuse-store-fuse_conn-in-fuse_req.patch
new file mode 100644 (file)
index 0000000..bcf6d9a
--- /dev/null
@@ -0,0 +1,101 @@
+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
+
diff --git a/queue-5.4/hwmon-amc6821-add-of_match-table.patch b/queue-5.4/hwmon-amc6821-add-of_match-table.patch
new file mode 100644 (file)
index 0000000..4037582
--- /dev/null
@@ -0,0 +1,56 @@
+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
+
diff --git a/queue-5.4/kbuild-move-wenum-compare-conditional-enum-conversio.patch b/queue-5.4/kbuild-move-wenum-compare-conditional-enum-conversio.patch
new file mode 100644 (file)
index 0000000..9396417
--- /dev/null
@@ -0,0 +1,72 @@
+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
+
diff --git a/queue-5.4/kvm-always-flush-async-pf-workqueue-when-vcpu-is-bei.patch b/queue-5.4/kvm-always-flush-async-pf-workqueue-when-vcpu-is-bei.patch
new file mode 100644 (file)
index 0000000..ecab60e
--- /dev/null
@@ -0,0 +1,183 @@
+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
+
diff --git a/queue-5.4/media-staging-ipu3-imgu-set-fields-before-media_enti.patch b/queue-5.4/media-staging-ipu3-imgu-set-fields-before-media_enti.patch
new file mode 100644 (file)
index 0000000..459d9c0
--- /dev/null
@@ -0,0 +1,81 @@
+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
+
diff --git a/queue-5.4/media-xc4000-fix-atomicity-violation-in-xc4000_get_f.patch b/queue-5.4/media-xc4000-fix-atomicity-violation-in-xc4000_get_f.patch
new file mode 100644 (file)
index 0000000..4c39e58
--- /dev/null
@@ -0,0 +1,79 @@
+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
+
diff --git a/queue-5.4/memtest-use-read-write-_once-in-memory-scanning.patch b/queue-5.4/memtest-use-read-write-_once-in-memory-scanning.patch
new file mode 100644 (file)
index 0000000..43ded8c
--- /dev/null
@@ -0,0 +1,45 @@
+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
+
diff --git a/queue-5.4/mmc-core-fix-switch-on-gp3-partition.patch b/queue-5.4/mmc-core-fix-switch-on-gp3-partition.patch
new file mode 100644 (file)
index 0000000..2df6365
--- /dev/null
@@ -0,0 +1,86 @@
+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
+
diff --git a/queue-5.4/mmc-tmio-avoid-concurrent-runs-of-mmc_request_done.patch b/queue-5.4/mmc-tmio-avoid-concurrent-runs-of-mmc_request_done.patch
new file mode 100644 (file)
index 0000000..7969c1c
--- /dev/null
@@ -0,0 +1,51 @@
+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
+
diff --git a/queue-5.4/mtd-rawnand-meson-fix-scrambling-mode-value-in-comma.patch b/queue-5.4/mtd-rawnand-meson-fix-scrambling-mode-value-in-comma.patch
new file mode 100644 (file)
index 0000000..09cd38b
--- /dev/null
@@ -0,0 +1,39 @@
+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
+
diff --git a/queue-5.4/nilfs2-fix-failure-to-detect-dat-corruption-in-btree.patch b/queue-5.4/nilfs2-fix-failure-to-detect-dat-corruption-in-btree.patch
new file mode 100644 (file)
index 0000000..a9ceaef
--- /dev/null
@@ -0,0 +1,131 @@
+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
+
diff --git a/queue-5.4/nilfs2-prevent-kernel-bug-at-submit_bh_wbc.patch b/queue-5.4/nilfs2-prevent-kernel-bug-at-submit_bh_wbc.patch
new file mode 100644 (file)
index 0000000..52b0e28
--- /dev/null
@@ -0,0 +1,44 @@
+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
+
diff --git a/queue-5.4/nilfs2-use-a-more-common-logging-style.patch b/queue-5.4/nilfs2-use-a-more-common-logging-style.patch
new file mode 100644 (file)
index 0000000..1165569
--- /dev/null
@@ -0,0 +1,1376 @@
+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
+
diff --git a/queue-5.4/nvmem-meson-efuse-fix-function-pointer-type-mismatch.patch b/queue-5.4/nvmem-meson-efuse-fix-function-pointer-type-mismatch.patch
new file mode 100644 (file)
index 0000000..0a964c7
--- /dev/null
@@ -0,0 +1,80 @@
+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
+
diff --git a/queue-5.4/parisc-do-not-hardcode-registers-in-checksum-functio.patch b/queue-5.4/parisc-do-not-hardcode-registers-in-checksum-functio.patch
new file mode 100644 (file)
index 0000000..230f0d9
--- /dev/null
@@ -0,0 +1,170 @@
+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
+
diff --git a/queue-5.4/parisc-fix-csum_ipv6_magic-on-32-bit-systems.patch b/queue-5.4/parisc-fix-csum_ipv6_magic-on-32-bit-systems.patch
new file mode 100644 (file)
index 0000000..b5c330e
--- /dev/null
@@ -0,0 +1,55 @@
+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
+
diff --git a/queue-5.4/parisc-fix-csum_ipv6_magic-on-64-bit-systems.patch b/queue-5.4/parisc-fix-csum_ipv6_magic-on-64-bit-systems.patch
new file mode 100644 (file)
index 0000000..298dea6
--- /dev/null
@@ -0,0 +1,55 @@
+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
+
diff --git a/queue-5.4/parisc-fix-ip_fast_csum.patch b/queue-5.4/parisc-fix-ip_fast_csum.patch
new file mode 100644 (file)
index 0000000..973ffa5
--- /dev/null
@@ -0,0 +1,66 @@
+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
+
diff --git a/queue-5.4/parisc-strip-upper-32-bit-of-sum-in-csum_ipv6_magic-.patch b/queue-5.4/parisc-strip-upper-32-bit-of-sum-in-csum_ipv6_magic-.patch
new file mode 100644 (file)
index 0000000..73fde9e
--- /dev/null
@@ -0,0 +1,55 @@
+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
+
diff --git a/queue-5.4/pci-drop-pci_device_remove-test-of-pci_dev-driver.patch b/queue-5.4/pci-drop-pci_device_remove-test-of-pci_dev-driver.patch
new file mode 100644 (file)
index 0000000..c704f2c
--- /dev/null
@@ -0,0 +1,58 @@
+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
+
diff --git a/queue-5.4/pci-pm-drain-runtime-idle-callbacks-before-driver-re.patch b/queue-5.4/pci-pm-drain-runtime-idle-callbacks-before-driver-re.patch
new file mode 100644 (file)
index 0000000..f84e20c
--- /dev/null
@@ -0,0 +1,76 @@
+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
+
diff --git a/queue-5.4/pm-sleep-wakeirq-fix-wake-irq-warning-in-system-susp.patch b/queue-5.4/pm-sleep-wakeirq-fix-wake-irq-warning-in-system-susp.patch
new file mode 100644 (file)
index 0000000..0982890
--- /dev/null
@@ -0,0 +1,59 @@
+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
+
diff --git a/queue-5.4/pm-suspend-set-mem_sleep_current-during-kernel-comma.patch b/queue-5.4/pm-suspend-set-mem_sleep_current-during-kernel-comma.patch
new file mode 100644 (file)
index 0000000..8dafac3
--- /dev/null
@@ -0,0 +1,42 @@
+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
+
diff --git a/queue-5.4/powerpc-fsl-fix-mfpmr-build-errors-with-newer-binuti.patch b/queue-5.4/powerpc-fsl-fix-mfpmr-build-errors-with-newer-binuti.patch
new file mode 100644 (file)
index 0000000..e36f065
--- /dev/null
@@ -0,0 +1,61 @@
+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
+
diff --git a/queue-5.4/revert-revert-md-raid5-wait-for-md_sb_change_pending.patch b/queue-5.4/revert-revert-md-raid5-wait-for-md_sb_change_pending.patch
new file mode 100644 (file)
index 0000000..ff6c14c
--- /dev/null
@@ -0,0 +1,72 @@
+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
+
diff --git a/queue-5.4/ring-buffer-fix-full_waiters_pending-in-poll.patch b/queue-5.4/ring-buffer-fix-full_waiters_pending-in-poll.patch
new file mode 100644 (file)
index 0000000..b0cca7f
--- /dev/null
@@ -0,0 +1,138 @@
+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
+
diff --git a/queue-5.4/ring-buffer-fix-resetting-of-shortest_full.patch b/queue-5.4/ring-buffer-fix-resetting-of-shortest_full.patch
new file mode 100644 (file)
index 0000000..3ad0669
--- /dev/null
@@ -0,0 +1,117 @@
+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
+
diff --git a/queue-5.4/s390-zcrypt-fix-reference-counting-on-zcrypt-card-ob.patch b/queue-5.4/s390-zcrypt-fix-reference-counting-on-zcrypt-card-ob.patch
new file mode 100644 (file)
index 0000000..3342613
--- /dev/null
@@ -0,0 +1,124 @@
+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
+
diff --git a/queue-5.4/selftests-mqueue-set-timeout-to-180-seconds.patch b/queue-5.4/selftests-mqueue-set-timeout-to-180-seconds.patch
new file mode 100644 (file)
index 0000000..e269b8e
--- /dev/null
@@ -0,0 +1,35 @@
+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
+
diff --git a/queue-5.4/serial-max310x-fix-null-pointer-dereference-in-i2c-i.patch b/queue-5.4/serial-max310x-fix-null-pointer-dereference-in-i2c-i.patch
new file mode 100644 (file)
index 0000000..e24d851
--- /dev/null
@@ -0,0 +1,62 @@
+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
+
index aca95c98c5559abcade5dc539a1c5ce5e4777ce7..4b0260389f6dc6f7ee3388ecd20e31fb54ce883c 100644 (file)
@@ -1,3 +1,79 @@
 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
diff --git a/queue-5.4/slimbus-core-remove-usage-of-the-deprecated-ida_simp.patch b/queue-5.4/slimbus-core-remove-usage-of-the-deprecated-ida_simp.patch
new file mode 100644 (file)
index 0000000..781d73b
--- /dev/null
@@ -0,0 +1,45 @@
+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
+
diff --git a/queue-5.4/smack-handle-smack64transmute-in-smack_inode_setsecu.patch b/queue-5.4/smack-handle-smack64transmute-in-smack_inode_setsecu.patch
new file mode 100644 (file)
index 0000000..82bf8be
--- /dev/null
@@ -0,0 +1,44 @@
+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
+
diff --git a/queue-5.4/smack-set-smack64transmute-only-for-dirs-in-smack_in.patch b/queue-5.4/smack-set-smack64transmute-only-for-dirs-in-smack_in.patch
new file mode 100644 (file)
index 0000000..c22637b
--- /dev/null
@@ -0,0 +1,38 @@
+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
+
diff --git a/queue-5.4/soc-fsl-qbman-add-cgr-update-function.patch b/queue-5.4/soc-fsl-qbman-add-cgr-update-function.patch
new file mode 100644 (file)
index 0000000..55c8b9a
--- /dev/null
@@ -0,0 +1,107 @@
+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, &params,
++                                       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
+
diff --git a/queue-5.4/soc-fsl-qbman-add-helper-for-sanity-checking-cgr-ops.patch b/queue-5.4/soc-fsl-qbman-add-helper-for-sanity-checking-cgr-ops.patch
new file mode 100644 (file)
index 0000000..5e14e29
--- /dev/null
@@ -0,0 +1,80 @@
+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
+
diff --git a/queue-5.4/soc-fsl-qbman-always-disable-interrupts-when-taking-.patch b/queue-5.4/soc-fsl-qbman-always-disable-interrupts-when-taking-.patch
new file mode 100644 (file)
index 0000000..69e6ef2
--- /dev/null
@@ -0,0 +1,73 @@
+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
+
diff --git a/queue-5.4/soc-fsl-qbman-use-raw-spinlock-for-cgr_lock.patch b/queue-5.4/soc-fsl-qbman-use-raw-spinlock-for-cgr_lock.patch
new file mode 100644 (file)
index 0000000..7a748c0
--- /dev/null
@@ -0,0 +1,132 @@
+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
+
diff --git a/queue-5.4/sparc-vdso-fix-return-value-of-__setup-handler.patch b/queue-5.4/sparc-vdso-fix-return-value-of-__setup-handler.patch
new file mode 100644 (file)
index 0000000..3e55d28
--- /dev/null
@@ -0,0 +1,57 @@
+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
+
diff --git a/queue-5.4/sparc64-nmi-watchdog-fix-return-value-of-__setup-han.patch b/queue-5.4/sparc64-nmi-watchdog-fix-return-value-of-__setup-han.patch
new file mode 100644 (file)
index 0000000..9dee6f5
--- /dev/null
@@ -0,0 +1,51 @@
+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
+
diff --git a/queue-5.4/speakup-fix-8bit-characters-from-direct-synth.patch b/queue-5.4/speakup-fix-8bit-characters-from-direct-synth.patch
new file mode 100644 (file)
index 0000000..c2ed6b3
--- /dev/null
@@ -0,0 +1,49 @@
+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
+
diff --git a/queue-5.4/timers-rename-del_timer_sync-to-timer_delete_sync.patch b/queue-5.4/timers-rename-del_timer_sync-to-timer_delete_sync.patch
new file mode 100644 (file)
index 0000000..38a9022
--- /dev/null
@@ -0,0 +1,130 @@
+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
+
diff --git a/queue-5.4/timers-update-kernel-doc-for-various-functions.patch b/queue-5.4/timers-update-kernel-doc-for-various-functions.patch
new file mode 100644 (file)
index 0000000..1725eb2
--- /dev/null
@@ -0,0 +1,265 @@
+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
+
diff --git a/queue-5.4/timers-use-del_timer_sync-even-on-up.patch b/queue-5.4/timers-use-del_timer_sync-even-on-up.patch
new file mode 100644 (file)
index 0000000..baa7391
--- /dev/null
@@ -0,0 +1,80 @@
+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
+
diff --git a/queue-5.4/ubi-check-for-too-small-leb-size-in-vtbl-code.patch b/queue-5.4/ubi-check-for-too-small-leb-size-in-vtbl-code.patch
new file mode 100644 (file)
index 0000000..373f248
--- /dev/null
@@ -0,0 +1,45 @@
+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
+
diff --git a/queue-5.4/ubi-correct-the-calculation-of-fastmap-size.patch b/queue-5.4/ubi-correct-the-calculation-of-fastmap-size.patch
new file mode 100644 (file)
index 0000000..b46ad07
--- /dev/null
@@ -0,0 +1,43 @@
+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
+
diff --git a/queue-5.4/ubifs-set-page-uptodate-in-the-correct-place.patch b/queue-5.4/ubifs-set-page-uptodate-in-the-correct-place.patch
new file mode 100644 (file)
index 0000000..dfec09c
--- /dev/null
@@ -0,0 +1,74 @@
+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
+
diff --git a/queue-5.4/usb-serial-add-device-id-for-verifone-adapter.patch b/queue-5.4/usb-serial-add-device-id-for-verifone-adapter.patch
new file mode 100644 (file)
index 0000000..e81f4dd
--- /dev/null
@@ -0,0 +1,94 @@
+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
+
diff --git a/queue-5.4/usb-serial-cp210x-add-id-for-mgp-instruments-pds100.patch b/queue-5.4/usb-serial-cp210x-add-id-for-mgp-instruments-pds100.patch
new file mode 100644 (file)
index 0000000..0bdbd1a
--- /dev/null
@@ -0,0 +1,44 @@
+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
+
diff --git a/queue-5.4/usb-serial-cp210x-add-pid-vid-for-tdk-nc0110013m-and.patch b/queue-5.4/usb-serial-cp210x-add-pid-vid-for-tdk-nc0110013m-and.patch
new file mode 100644 (file)
index 0000000..d29076b
--- /dev/null
@@ -0,0 +1,36 @@
+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
+
diff --git a/queue-5.4/usb-serial-ftdi_sio-add-support-for-gmc-z216c-adapte.patch b/queue-5.4/usb-serial-ftdi_sio-add-support-for-gmc-z216c-adapte.patch
new file mode 100644 (file)
index 0000000..03579f1
--- /dev/null
@@ -0,0 +1,53 @@
+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
+
diff --git a/queue-5.4/usb-serial-option-add-meig-smart-slm320-product.patch b/queue-5.4/usb-serial-option-add-meig-smart-slm320-product.patch
new file mode 100644 (file)
index 0000000..a6a59b4
--- /dev/null
@@ -0,0 +1,85 @@
+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
+
diff --git a/queue-5.4/vfio-platform-disable-virqfds-on-cleanup.patch b/queue-5.4/vfio-platform-disable-virqfds-on-cleanup.patch
new file mode 100644 (file)
index 0000000..c3f0dcd
--- /dev/null
@@ -0,0 +1,44 @@
+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
+
diff --git a/queue-5.4/wifi-brcmfmac-fix-use-after-free-bug-in-brcmf_cfg802.patch b/queue-5.4/wifi-brcmfmac-fix-use-after-free-bug-in-brcmf_cfg802.patch
new file mode 100644 (file)
index 0000000..85d2b1c
--- /dev/null
@@ -0,0 +1,77 @@
+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
+
diff --git a/queue-5.4/x86-cpu-amd-update-the-zenbleed-microcode-revisions.patch b/queue-5.4/x86-cpu-amd-update-the-zenbleed-microcode-revisions.patch
new file mode 100644 (file)
index 0000000..001c457
--- /dev/null
@@ -0,0 +1,44 @@
+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
+