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

diff --git a/queue-4.19/ahci-asm1064-asm1166-don-t-limit-reported-ports.patch b/queue-4.19/ahci-asm1064-asm1166-don-t-limit-reported-ports.patch
new file mode 100644 (file)
index 0000000..f040478
--- /dev/null
@@ -0,0 +1,89 @@
+From ac6b4d29a34de7f7c66d77d242c1df41c07b9373 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 6b1562fed85ed..ab3ea47ecce3a 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -634,19 +634,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-4.19/ahci-asm1064-correct-count-of-reported-ports.patch b/queue-4.19/ahci-asm1064-correct-count-of-reported-ports.patch
new file mode 100644 (file)
index 0000000..a728da5
--- /dev/null
@@ -0,0 +1,60 @@
+From 26bcc6f3f9548334f78f32199864a897b547a668 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 abdfd440987b4..6b1562fed85ed 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -634,9 +634,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-4.19/arm-dts-marvell-fix-maxium-maxim-typo-in-brownstone-.patch b/queue-4.19/arm-dts-marvell-fix-maxium-maxim-typo-in-brownstone-.patch
new file mode 100644 (file)
index 0000000..e84fcc6
--- /dev/null
@@ -0,0 +1,46 @@
+From eac6e50536430d612ac3e1b7e967459c7acb8972 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 0fdcc2edcf4b6..f12d5aa773f30 100644
+--- a/arch/arm/boot/dts/mmp2-brownstone.dts
++++ b/arch/arm/boot/dts/mmp2-brownstone.dts
+@@ -30,7 +30,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-4.19/arm-dts-mmp2-brownstone-don-t-redeclare-phandle-refe.patch b/queue-4.19/arm-dts-mmp2-brownstone-don-t-redeclare-phandle-refe.patch
new file mode 100644 (file)
index 0000000..1047bdb
--- /dev/null
@@ -0,0 +1,371 @@
+From 87a0058ac3794889406cbed55db219139cafb7d1 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 350208c5e1ed2..0fdcc2edcf4b6 100644
+--- a/arch/arm/boot/dts/mmp2-brownstone.dts
++++ b/arch/arm/boot/dts/mmp2-brownstone.dts
+@@ -21,176 +21,174 @@ chosen {
+       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-4.19/clk-qcom-gcc-ipq8074-fix-terminating-of-frequency-ta.patch b/queue-4.19/clk-qcom-gcc-ipq8074-fix-terminating-of-frequency-ta.patch
new file mode 100644 (file)
index 0000000..226ccce
--- /dev/null
@@ -0,0 +1,51 @@
+From 569e0074a68509876455eb78047a732f53960ba3 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 eff38d22738c4..e38a1f87263b8 100644
+--- a/drivers/clk/qcom/gcc-ipq8074.c
++++ b/drivers/clk/qcom/gcc-ipq8074.c
+@@ -980,6 +980,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 = {
+@@ -1085,6 +1086,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-4.19/clk-qcom-mmcc-apq8084-fix-terminating-of-frequency-t.patch b/queue-4.19/clk-qcom-mmcc-apq8084-fix-terminating-of-frequency-t.patch
new file mode 100644 (file)
index 0000000..5bef043
--- /dev/null
@@ -0,0 +1,51 @@
+From 3a1b427ff627f15e2d837ead93fd11715fd40b8a 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 4ce1d7c88377f..36a40b0ddfa1f 100644
+--- a/drivers/clk/qcom/mmcc-apq8084.c
++++ b/drivers/clk/qcom/mmcc-apq8084.c
+@@ -341,6 +341,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 = {
+@@ -365,6 +366,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-4.19/clk-qcom-mmcc-msm8974-fix-terminating-of-frequency-t.patch b/queue-4.19/clk-qcom-mmcc-msm8974-fix-terminating-of-frequency-t.patch
new file mode 100644 (file)
index 0000000..7238f90
--- /dev/null
@@ -0,0 +1,51 @@
+From 7acfd3e5c473591e5b1a6ec2a358d31c26d6a358 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 91818516c3e0c..124d21f19e2c7 100644
+--- a/drivers/clk/qcom/mmcc-msm8974.c
++++ b/drivers/clk/qcom/mmcc-msm8974.c
+@@ -291,6 +291,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 = {
+@@ -315,6 +316,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-4.19/crypto-qat-fix-double-free-during-reset.patch b/queue-4.19/crypto-qat-fix-double-free-during-reset.patch
new file mode 100644 (file)
index 0000000..08e1099
--- /dev/null
@@ -0,0 +1,42 @@
+From 1cf8737b7847080156bbd3e3b86fe54b49a7bf27 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 9225d060e18f4..44b91cb73dd19 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-4.19/crypto-qat-resolve-race-condition-during-aer-recover.patch b/queue-4.19/crypto-qat-resolve-race-condition-during-aer-recover.patch
new file mode 100644 (file)
index 0000000..6acd5e8
--- /dev/null
@@ -0,0 +1,92 @@
+From d4c80f722a31411015c24be063f690885d0c33d5 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 44b91cb73dd19..7242a1ee86de7 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-4.19/dm-raid-fix-lockdep-waring-in-pers-hot_add_disk.patch b/queue-4.19/dm-raid-fix-lockdep-waring-in-pers-hot_add_disk.patch
new file mode 100644 (file)
index 0000000..0bbad52
--- /dev/null
@@ -0,0 +1,49 @@
+From 1b3818962a987bdc835b4603c3028f209b754aa5 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 1759134fce824..2a8746f9c6d87 100644
+--- a/drivers/md/dm-raid.c
++++ b/drivers/md/dm-raid.c
+@@ -4023,7 +4023,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-4.19/drm-imx-ipuv3-do-not-return-negative-values-from-.ge.patch b/queue-4.19/drm-imx-ipuv3-do-not-return-negative-values-from-.ge.patch
new file mode 100644 (file)
index 0000000..929c14b
--- /dev/null
@@ -0,0 +1,47 @@
+From daebe5010bd15ac347ac995a4f66777fa72d664f 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 a96d99cbec4d0..290f68b9adfea 100644
+--- a/drivers/gpu/drm/imx/parallel-display.c
++++ b/drivers/gpu/drm/imx/parallel-display.c
+@@ -78,14 +78,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-4.19/drm-imx-pd-use-bus-format-flags-provided-by-the-brid.patch b/queue-4.19/drm-imx-pd-use-bus-format-flags-provided-by-the-brid.patch
new file mode 100644 (file)
index 0000000..658faaf
--- /dev/null
@@ -0,0 +1,311 @@
+From 1da708797a30d20a5033729bd6afc7f1da7a68a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jan 2020 14:55:09 +0100
+Subject: drm/imx: pd: Use bus format/flags provided by the bridge when
+ available
+
+From: Boris Brezillon <boris.brezillon@collabora.com>
+
+[ Upstream commit fe141cedc4333e3b76307f096e02b2c1e60f65d5 ]
+
+Now that bridges can expose the bus format/flags they expect, we can
+use those instead of the relying on the display_info provided by the
+connector (which is only valid if the encoder is directly connected
+to bridge element driving the panel/display).
+
+We also explicitly expose the bus formats supported by our encoder by
+filling encoder->output_bus_caps with proper info.
+
+v10:
+* Add changelog to the commit message
+* Use kmalloc() instead of kcalloc()
+* Add a dev_warn() when unsupported flags are requested
+
+v8 -> v9:
+* No changes
+
+v7:
+* Add an imx_pd_format_supported() helper (suggested by Philipp)
+* Simplify imx_pd_bridge_atomic_get_output_bus_fmts() (suggested by Philipp)
+* Simplify imx_pd_bridge_atomic_get_input_bus_fmts()
+* Explicitly set the duplicate/destro_state() and reset() hooks
+
+v4 -> v6:
+* Patch was not part of the series
+
+v3 (all suggested by Philipp):
+* Adjust to match core changes
+* Propagate output format to input format
+* Pick a default value when output_fmt = _FIXED
+* Add missing BGR888 and GBR888 fmts to imx_pd_bus_fmts[]
+
+v2:
+* Adjust things to match the new bus-format negotiation infra
+
+Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
+Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
+Link: https://patchwork.freedesktop.org/patch/msgid/20200128135514.108171-8-boris.brezillon@collabora.com
+Stable-dep-of: c2da9ada6496 ("drm/imx/ipuv3: do not return negative values from .get_modes()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/imx/parallel-display.c | 176 +++++++++++++++++++++----
+ 1 file changed, 151 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
+index e9dff31b377c4..a96d99cbec4d0 100644
+--- a/drivers/gpu/drm/imx/parallel-display.c
++++ b/drivers/gpu/drm/imx/parallel-display.c
+@@ -29,6 +29,7 @@
+ struct imx_parallel_display {
+       struct drm_connector connector;
+       struct drm_encoder encoder;
++      struct drm_bridge bridge;
+       struct device *dev;
+       void *edid;
+       int edid_len;
+@@ -36,7 +37,7 @@ struct imx_parallel_display {
+       u32 bus_flags;
+       struct drm_display_mode mode;
+       struct drm_panel *panel;
+-      struct drm_bridge *bridge;
++      struct drm_bridge *next_bridge;
+ };
+ static inline struct imx_parallel_display *con_to_imxpd(struct drm_connector *c)
+@@ -49,6 +50,11 @@ static inline struct imx_parallel_display *enc_to_imxpd(struct drm_encoder *e)
+       return container_of(e, struct imx_parallel_display, encoder);
+ }
++static inline struct imx_parallel_display *bridge_to_imxpd(struct drm_bridge *b)
++{
++      return container_of(b, struct imx_parallel_display, bridge);
++}
++
+ static int imx_pd_connector_get_modes(struct drm_connector *connector)
+ {
+       struct imx_parallel_display *imxpd = con_to_imxpd(connector);
+@@ -99,37 +105,148 @@ static struct drm_encoder *imx_pd_connector_best_encoder(
+       return &imxpd->encoder;
+ }
+-static void imx_pd_encoder_enable(struct drm_encoder *encoder)
++static void imx_pd_bridge_enable(struct drm_bridge *bridge)
+ {
+-      struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
++      struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge);
+       drm_panel_prepare(imxpd->panel);
+       drm_panel_enable(imxpd->panel);
+ }
+-static void imx_pd_encoder_disable(struct drm_encoder *encoder)
++static void imx_pd_bridge_disable(struct drm_bridge *bridge)
+ {
+-      struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
++      struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge);
+       drm_panel_disable(imxpd->panel);
+       drm_panel_unprepare(imxpd->panel);
+ }
+-static int imx_pd_encoder_atomic_check(struct drm_encoder *encoder,
+-                                     struct drm_crtc_state *crtc_state,
+-                                     struct drm_connector_state *conn_state)
++static const u32 imx_pd_bus_fmts[] = {
++      MEDIA_BUS_FMT_RGB888_1X24,
++      MEDIA_BUS_FMT_BGR888_1X24,
++      MEDIA_BUS_FMT_GBR888_1X24,
++      MEDIA_BUS_FMT_RGB666_1X18,
++      MEDIA_BUS_FMT_RGB666_1X24_CPADHI,
++      MEDIA_BUS_FMT_RGB565_1X16,
++};
++
++static u32 *
++imx_pd_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
++                                       struct drm_bridge_state *bridge_state,
++                                       struct drm_crtc_state *crtc_state,
++                                       struct drm_connector_state *conn_state,
++                                       unsigned int *num_output_fmts)
+ {
+-      struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state);
+       struct drm_display_info *di = &conn_state->connector->display_info;
+-      struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
++      struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge);
++      u32 *output_fmts;
+-      if (!imxpd->bus_format && di->num_bus_formats) {
+-              imx_crtc_state->bus_flags = di->bus_flags;
+-              imx_crtc_state->bus_format = di->bus_formats[0];
+-      } else {
+-              imx_crtc_state->bus_flags = imxpd->bus_flags;
+-              imx_crtc_state->bus_format = imxpd->bus_format;
++      if (!imxpd->bus_format && !di->num_bus_formats) {
++              *num_output_fmts = ARRAY_SIZE(imx_pd_bus_fmts);
++              return kmemdup(imx_pd_bus_fmts, sizeof(imx_pd_bus_fmts),
++                             GFP_KERNEL);
++      }
++
++      *num_output_fmts = 1;
++      output_fmts = kmalloc(sizeof(*output_fmts), GFP_KERNEL);
++      if (!output_fmts)
++              return NULL;
++
++      if (!imxpd->bus_format && di->num_bus_formats)
++              output_fmts[0] = di->bus_formats[0];
++      else
++              output_fmts[0] = imxpd->bus_format;
++
++      return output_fmts;
++}
++
++static bool imx_pd_format_supported(u32 output_fmt)
++{
++      unsigned int i;
++
++      for (i = 0; i < ARRAY_SIZE(imx_pd_bus_fmts); i++) {
++              if (imx_pd_bus_fmts[i] == output_fmt)
++                      return true;
++      }
++
++      return false;
++}
++
++static u32 *
++imx_pd_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
++                                      struct drm_bridge_state *bridge_state,
++                                      struct drm_crtc_state *crtc_state,
++                                      struct drm_connector_state *conn_state,
++                                      u32 output_fmt,
++                                      unsigned int *num_input_fmts)
++{
++      struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge);
++      u32 *input_fmts;
++
++      /*
++       * If the next bridge does not support bus format negotiation, let's
++       * use the static bus format definition (imxpd->bus_format) if it's
++       * specified, RGB888 when it's not.
++       */
++      if (output_fmt == MEDIA_BUS_FMT_FIXED)
++              output_fmt = imxpd->bus_format ? : MEDIA_BUS_FMT_RGB888_1X24;
++
++      /* Now make sure the requested output format is supported. */
++      if ((imxpd->bus_format && imxpd->bus_format != output_fmt) ||
++          !imx_pd_format_supported(output_fmt)) {
++              *num_input_fmts = 0;
++              return NULL;
++      }
++
++      *num_input_fmts = 1;
++      input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL);
++      if (!input_fmts)
++              return NULL;
++
++      input_fmts[0] = output_fmt;
++      return input_fmts;
++}
++
++static int imx_pd_bridge_atomic_check(struct drm_bridge *bridge,
++                                    struct drm_bridge_state *bridge_state,
++                                    struct drm_crtc_state *crtc_state,
++                                    struct drm_connector_state *conn_state)
++{
++      struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state);
++      struct drm_display_info *di = &conn_state->connector->display_info;
++      struct imx_parallel_display *imxpd = bridge_to_imxpd(bridge);
++      struct drm_bridge_state *next_bridge_state = NULL;
++      struct drm_bridge *next_bridge;
++      u32 bus_flags, bus_fmt;
++
++      next_bridge = drm_bridge_get_next_bridge(bridge);
++      if (next_bridge)
++              next_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state,
++                                                                  next_bridge);
++
++      if (next_bridge_state)
++              bus_flags = next_bridge_state->input_bus_cfg.flags;
++      else if (!imxpd->bus_format && di->num_bus_formats)
++              bus_flags = di->bus_flags;
++      else
++              bus_flags = imxpd->bus_flags;
++
++      bus_fmt = bridge_state->input_bus_cfg.format;
++      if (!imx_pd_format_supported(bus_fmt))
++              return -EINVAL;
++
++      if (bus_flags &
++          ~(DRM_BUS_FLAG_DE_LOW | DRM_BUS_FLAG_DE_HIGH |
++            DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE |
++            DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)) {
++              dev_warn(imxpd->dev, "invalid bus_flags (%x)\n", bus_flags);
++              return -EINVAL;
+       }
++
++      bridge_state->output_bus_cfg.flags = bus_flags;
++      bridge_state->input_bus_cfg.flags = bus_flags;
++      imx_crtc_state->bus_flags = bus_flags;
++      imx_crtc_state->bus_format = bridge_state->input_bus_cfg.format;
+       imx_crtc_state->di_hsync_pin = 2;
+       imx_crtc_state->di_vsync_pin = 3;
+@@ -153,10 +270,15 @@ static const struct drm_encoder_funcs imx_pd_encoder_funcs = {
+       .destroy = imx_drm_encoder_destroy,
+ };
+-static const struct drm_encoder_helper_funcs imx_pd_encoder_helper_funcs = {
+-      .enable = imx_pd_encoder_enable,
+-      .disable = imx_pd_encoder_disable,
+-      .atomic_check = imx_pd_encoder_atomic_check,
++static const struct drm_bridge_funcs imx_pd_bridge_funcs = {
++      .enable = imx_pd_bridge_enable,
++      .disable = imx_pd_bridge_disable,
++      .atomic_reset = drm_atomic_helper_bridge_reset,
++      .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
++      .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
++      .atomic_check = imx_pd_bridge_atomic_check,
++      .atomic_get_input_bus_fmts = imx_pd_bridge_atomic_get_input_bus_fmts,
++      .atomic_get_output_bus_fmts = imx_pd_bridge_atomic_get_output_bus_fmts,
+ };
+ static int imx_pd_register(struct drm_device *drm,
+@@ -176,11 +298,13 @@ static int imx_pd_register(struct drm_device *drm,
+        */
+       imxpd->connector.dpms = DRM_MODE_DPMS_OFF;
+-      drm_encoder_helper_add(encoder, &imx_pd_encoder_helper_funcs);
+       drm_encoder_init(drm, encoder, &imx_pd_encoder_funcs,
+                        DRM_MODE_ENCODER_NONE, NULL);
+-      if (!imxpd->bridge) {
++      imxpd->bridge.funcs = &imx_pd_bridge_funcs;
++      drm_bridge_attach(encoder, &imxpd->bridge, NULL);
++
++      if (!imxpd->next_bridge) {
+               drm_connector_helper_add(&imxpd->connector,
+                               &imx_pd_connector_helper_funcs);
+               drm_connector_init(drm, &imxpd->connector,
+@@ -191,8 +315,9 @@ static int imx_pd_register(struct drm_device *drm,
+       if (imxpd->panel)
+               drm_panel_attach(imxpd->panel, &imxpd->connector);
+-      if (imxpd->bridge) {
+-              ret = drm_bridge_attach(encoder, imxpd->bridge, NULL);
++      if (imxpd->next_bridge) {
++              ret = drm_bridge_attach(encoder, imxpd->next_bridge,
++                                      &imxpd->bridge);
+               if (ret < 0) {
+                       dev_err(imxpd->dev, "failed to attach bridge: %d\n",
+                               ret);
+@@ -237,7 +362,8 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
+       imxpd->bus_format = bus_format;
+       /* port@1 is the output port */
+-      ret = drm_of_find_panel_or_bridge(np, 1, 0, &imxpd->panel, &imxpd->bridge);
++      ret = drm_of_find_panel_or_bridge(np, 1, 0, &imxpd->panel,
++                                        &imxpd->next_bridge);
+       if (ret && ret != -ENODEV)
+               return ret;
+-- 
+2.43.0
+
diff --git a/queue-4.19/drm-vc4-hdmi-do-not-return-negative-values-from-.get.patch b/queue-4.19/drm-vc4-hdmi-do-not-return-negative-values-from-.get.patch
new file mode 100644 (file)
index 0000000..e6fe2c1
--- /dev/null
@@ -0,0 +1,39 @@
+From 7cf20b631a75a18b2e20d7a3b5936ad5ba341d63 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 1161662664577..013dfc63c824e 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -276,7 +276,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-4.19/ext4-fix-corruption-during-on-line-resize.patch b/queue-4.19/ext4-fix-corruption-during-on-line-resize.patch
new file mode 100644 (file)
index 0000000..22a6b82
--- /dev/null
@@ -0,0 +1,79 @@
+From c2f26e7ce51958bc1eb98f1e35ab0043a418c273 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 97af09d6e7e6c..7d615c00b632b 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-4.19/fat-fix-uninitialized-field-in-nostale-filehandles.patch b/queue-4.19/fat-fix-uninitialized-field-in-nostale-filehandles.patch
new file mode 100644 (file)
index 0000000..d4b6ab0
--- /dev/null
@@ -0,0 +1,49 @@
+From d75c3e07af2e7db054a9e2483c4e48a3dbdb8965 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 eb192656fba27..f442a8d2f114b 100644
+--- a/fs/fat/nfs.c
++++ b/fs/fat/nfs.c
+@@ -139,6 +139,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-4.19/fuse-don-t-unhash-root.patch b/queue-4.19/fuse-don-t-unhash-root.patch
new file mode 100644 (file)
index 0000000..23b4f9c
--- /dev/null
@@ -0,0 +1,54 @@
+From dcee3958857991a5564ecac25fe6e7490f65eb1e 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 1c754a02fb06b..aa0a5e3960909 100644
+--- a/fs/fuse/fuse_i.h
++++ b/fs/fuse/fuse_i.h
+@@ -706,7 +706,6 @@ static inline u64 get_node_id(struct inode *inode)
+ 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 3b51c881baf8c..a67769c357b2d 100644
+--- a/fs/fuse/inode.c
++++ b/fs/fuse/inode.c
+@@ -324,8 +324,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-4.19/hwmon-amc6821-add-of_match-table.patch b/queue-4.19/hwmon-amc6821-add-of_match-table.patch
new file mode 100644 (file)
index 0000000..ff8793a
--- /dev/null
@@ -0,0 +1,56 @@
+From 8bf3e0e5bbeb59a2c6ba4c79106fcf960b12769c 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 46b4e35fd5555..b562337df7b3c 100644
+--- a/drivers/hwmon/amc6821.c
++++ b/drivers/hwmon/amc6821.c
+@@ -1003,10 +1003,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-4.19/kbuild-move-wenum-compare-conditional-enum-conversio.patch b/queue-4.19/kbuild-move-wenum-compare-conditional-enum-conversio.patch
new file mode 100644 (file)
index 0000000..293297a
--- /dev/null
@@ -0,0 +1,71 @@
+From 82f7b316fe1ee30f4a71e5657a67c323fde9cc8c 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 e15cd63428ba7..c2e41daf373f8 100644
+--- a/scripts/Makefile.extrawarn
++++ b/scripts/Makefile.extrawarn
+@@ -75,5 +75,7 @@ KBUILD_CFLAGS += $(call cc-disable-warning, uninitialized)
+ 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-4.19/kvm-always-flush-async-pf-workqueue-when-vcpu-is-bei.patch b/queue-4.19/kvm-always-flush-async-pf-workqueue-when-vcpu-is-bei.patch
new file mode 100644 (file)
index 0000000..1c864d0
--- /dev/null
@@ -0,0 +1,183 @@
+From 58d41c9ae61c4309315ff6e9e3817d85beb11350 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 c9861c2315e8e..3e17f8c7432c1 100644
+--- a/virt/kvm/async_pf.c
++++ b/virt/kvm/async_pf.c
+@@ -110,7 +110,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)
+@@ -137,7 +157,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
+@@ -149,7 +168,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);
+@@ -173,7 +195,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);
+       }
+ }
+@@ -202,7 +224,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-4.19/media-xc4000-fix-atomicity-violation-in-xc4000_get_f.patch b/queue-4.19/media-xc4000-fix-atomicity-violation-in-xc4000_get_f.patch
new file mode 100644 (file)
index 0000000..a38eb60
--- /dev/null
@@ -0,0 +1,79 @@
+From 4dad784985406e39c7f0262747c2e38be3f49fa4 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 0ef8f054a7950..6017602aead62 100644
+--- a/drivers/media/tuners/xc4000.c
++++ b/drivers/media/tuners/xc4000.c
+@@ -1527,10 +1527,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;
+@@ -1541,8 +1541,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-4.19/memtest-use-read-write-_once-in-memory-scanning.patch b/queue-4.19/memtest-use-read-write-_once-in-memory-scanning.patch
new file mode 100644 (file)
index 0000000..00dedd7
--- /dev/null
@@ -0,0 +1,45 @@
+From ba55d8ed17c95d28e74e5228778900e2c19ddfd0 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-4.19/mmc-core-fix-switch-on-gp3-partition.patch b/queue-4.19/mmc-core-fix-switch-on-gp3-partition.patch
new file mode 100644 (file)
index 0000000..97a6584
--- /dev/null
@@ -0,0 +1,86 @@
+From d47ba4aa9b89095f85eb19a33a50cffd55da8dd8 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 ef9422917e1ca..c3b329946429c 100644
+--- a/drivers/mmc/core/block.c
++++ b/drivers/mmc/core/block.c
+@@ -851,10 +851,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)
+@@ -869,10 +870,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-4.19/mmc-tmio-avoid-concurrent-runs-of-mmc_request_done.patch b/queue-4.19/mmc-tmio-avoid-concurrent-runs-of-mmc_request_done.patch
new file mode 100644 (file)
index 0000000..4430676
--- /dev/null
@@ -0,0 +1,51 @@
+From 79316ff6e0f07a610c1fb471b40244900023e8c8 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 f819757e125e0..ae8913e5adc70 100644
+--- a/drivers/mmc/host/tmio_mmc_core.c
++++ b/drivers/mmc/host/tmio_mmc_core.c
+@@ -213,6 +213,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-4.19/nilfs2-fix-failure-to-detect-dat-corruption-in-btree.patch b/queue-4.19/nilfs2-fix-failure-to-detect-dat-corruption-in-btree.patch
new file mode 100644 (file)
index 0000000..1af227c
--- /dev/null
@@ -0,0 +1,131 @@
+From dd86ad28d5435456f39cb57a8bc3953119b80b66 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-4.19/nilfs2-prevent-kernel-bug-at-submit_bh_wbc.patch b/queue-4.19/nilfs2-prevent-kernel-bug-at-submit_bh_wbc.patch
new file mode 100644 (file)
index 0000000..0f1d0d8
--- /dev/null
@@ -0,0 +1,44 @@
+From 8b0aab043fdb946b11ae8d864f2ba2ea72b576e9 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-4.19/nilfs2-use-a-more-common-logging-style.patch b/queue-4.19/nilfs2-use-a-more-common-logging-style.patch
new file mode 100644 (file)
index 0000000..08925fc
--- /dev/null
@@ -0,0 +1,1376 @@
+From 99bf688a2f7d846e7e7c3ab0a7b120dadbb46aef 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 dfb2083b8ce1c..ecb5e4cf058b5 100644
+--- a/fs/nilfs2/ioctl.c
++++ b/fs/nilfs2/ioctl.c
+@@ -574,25 +574,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;
+       }
+@@ -842,8 +842,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;
+ }
+@@ -952,7 +951,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 cca30f0f965c5..d8dc6e546febe 100644
+--- a/fs/nilfs2/nilfs.h
++++ b/fs/nilfs2/nilfs.h
+@@ -321,6 +321,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 e5fee7fac9154..762dd277099eb 100644
+--- a/fs/nilfs2/page.c
++++ b/fs/nilfs2/page.c
+@@ -401,9 +401,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);
+@@ -419,9 +418,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 99bcb4ab47a61..6d33eecff2619 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.
+  */
+@@ -186,8 +186,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],
+@@ -257,7 +256,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] &&
+@@ -367,9 +366,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;
+       }
+@@ -563,7 +562,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;
+@@ -661,8 +660,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
+@@ -794,7 +792,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;
+@@ -810,8 +808,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;
+               }
+       }
+@@ -847,10 +844,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)
+@@ -913,7 +910,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;
+@@ -921,7 +918,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;
+@@ -940,12 +937,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;
+       }
+@@ -973,7 +970,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;
+ }
+@@ -993,7 +990,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;
+@@ -1002,7 +999,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;
+@@ -1099,7 +1096,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;
+@@ -1162,8 +1159,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;
+       }
+@@ -1193,9 +1190,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;
+               }
+@@ -1254,7 +1251,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;
+ }
+@@ -1357,7 +1354,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-4.19/parisc-do-not-hardcode-registers-in-checksum-functio.patch b/queue-4.19/parisc-do-not-hardcode-registers-in-checksum-functio.patch
new file mode 100644 (file)
index 0000000..a41adaf
--- /dev/null
@@ -0,0 +1,170 @@
+From 83b44a145746d0c0cc73bbd6c2e9bd5b7533797a 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-4.19/parisc-fix-csum_ipv6_magic-on-32-bit-systems.patch b/queue-4.19/parisc-fix-csum_ipv6_magic-on-32-bit-systems.patch
new file mode 100644 (file)
index 0000000..0ca297a
--- /dev/null
@@ -0,0 +1,55 @@
+From f3fc09f38ebd520863b2ab0f2ae02c4454541b16 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-4.19/parisc-fix-csum_ipv6_magic-on-64-bit-systems.patch b/queue-4.19/parisc-fix-csum_ipv6_magic-on-64-bit-systems.patch
new file mode 100644 (file)
index 0000000..cf2a4e0
--- /dev/null
@@ -0,0 +1,55 @@
+From 0cc85c467f723a50c503d8bdf3e2e9604c9a7b52 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-4.19/parisc-fix-ip_fast_csum.patch b/queue-4.19/parisc-fix-ip_fast_csum.patch
new file mode 100644 (file)
index 0000000..1116784
--- /dev/null
@@ -0,0 +1,66 @@
+From da648d10829e55e3062bef8085c9e4ce3e5b6d37 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-4.19/parisc-strip-upper-32-bit-of-sum-in-csum_ipv6_magic-.patch b/queue-4.19/parisc-strip-upper-32-bit-of-sum-in-csum_ipv6_magic-.patch
new file mode 100644 (file)
index 0000000..852d3fb
--- /dev/null
@@ -0,0 +1,55 @@
+From a0e80f9c8e7c7c3408ee851834b0230a5cf593fd 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-4.19/pci-drop-pci_device_remove-test-of-pci_dev-driver.patch b/queue-4.19/pci-drop-pci_device_remove-test-of-pci_dev-driver.patch
new file mode 100644 (file)
index 0000000..fe725a6
--- /dev/null
@@ -0,0 +1,58 @@
+From 6fd80a9071ad5ea0e7d945db22bdf1e8f8140a68 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 78ae1cab9af70..2e5402b09c1ad 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-4.19/pci-pm-drain-runtime-idle-callbacks-before-driver-re.patch b/queue-4.19/pci-pm-drain-runtime-idle-callbacks-before-driver-re.patch
new file mode 100644 (file)
index 0000000..bf61365
--- /dev/null
@@ -0,0 +1,76 @@
+From b9d80cd02698d039f45414aced21fa8e3291b981 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 2e5402b09c1ad..031908e42fb54 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-4.19/pm-sleep-wakeirq-fix-wake-irq-warning-in-system-susp.patch b/queue-4.19/pm-sleep-wakeirq-fix-wake-irq-warning-in-system-susp.patch
new file mode 100644 (file)
index 0000000..d7b8e2b
--- /dev/null
@@ -0,0 +1,59 @@
+From e1ff83dbd2ba5445062363fbe0319ff4a382ff23 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 e7ba514999163..bc3637b45cbf7 100644
+--- a/drivers/base/power/wakeirq.c
++++ b/drivers/base/power/wakeirq.c
+@@ -376,8 +376,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-4.19/pm-suspend-set-mem_sleep_current-during-kernel-comma.patch b/queue-4.19/pm-suspend-set-mem_sleep_current-during-kernel-comma.patch
new file mode 100644 (file)
index 0000000..ad81a2f
--- /dev/null
@@ -0,0 +1,42 @@
+From 0c3fe9b38f44f9d7512e69f915715297a20d0900 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 0bd595a0b6103..7a080015a1b3c 100644
+--- a/kernel/power/suspend.c
++++ b/kernel/power/suspend.c
+@@ -202,6 +202,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-4.19/powerpc-fsl-fix-mfpmr-build-errors-with-newer-binuti.patch b/queue-4.19/powerpc-fsl-fix-mfpmr-build-errors-with-newer-binuti.patch
new file mode 100644 (file)
index 0000000..0fe1c60
--- /dev/null
@@ -0,0 +1,61 @@
+From c6cfea0aa39a4a2af3e5ff374ea17d5bca9af03f 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-4.19/revert-revert-md-raid5-wait-for-md_sb_change_pending.patch b/queue-4.19/revert-revert-md-raid5-wait-for-md_sb_change_pending.patch
new file mode 100644 (file)
index 0000000..f9351c1
--- /dev/null
@@ -0,0 +1,72 @@
+From 19975ad2eaf6c29185953381f42722e7d03e0562 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 e2fcc09a18cdb..b98abe927d06b 100644
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -44,6 +44,7 @@
+  */
+ #include <linux/blkdev.h>
++#include <linux/delay.h>
+ #include <linux/kthread.h>
+ #include <linux/raid/pq.h>
+ #include <linux/async_tx.h>
+@@ -6329,7 +6330,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-4.19/s390-zcrypt-fix-reference-counting-on-zcrypt-card-ob.patch b/queue-4.19/s390-zcrypt-fix-reference-counting-on-zcrypt-card-ob.patch
new file mode 100644 (file)
index 0000000..3363b00
--- /dev/null
@@ -0,0 +1,124 @@
+From 6d76aed2af33d6785e991ce06f5fbc168c0bb689 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 b7cb897cd83e0..3a47e622db10e 100644
+--- a/drivers/s390/crypto/zcrypt_api.c
++++ b/drivers/s390/crypto/zcrypt_api.c
+@@ -158,6 +158,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);
+@@ -177,6 +178,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
+
index aca95c98c5559abcade5dc539a1c5ce5e4777ce7..956af7ae206299ca27ab420a3a4472a5edb40c31 100644 (file)
@@ -1,3 +1,68 @@
 documentation-hw-vuln-update-spectre-doc.patch
 x86-cpu-support-amd-automatic-ibrs.patch
 x86-bugs-use-sysfs_emit.patch
+timer-trace-replace-deprecated-vsprintf-pointer-exte.patch
+timer-trace-improve-timer-tracing.patch
+timers-prepare-support-for-preempt_rt.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
+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
+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
+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
+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-don-t-unhash-root.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
+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
+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-imx-pd-use-bus-format-flags-provided-by-the-brid.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
diff --git a/queue-4.19/slimbus-core-remove-usage-of-the-deprecated-ida_simp.patch b/queue-4.19/slimbus-core-remove-usage-of-the-deprecated-ida_simp.patch
new file mode 100644 (file)
index 0000000..580e6fa
--- /dev/null
@@ -0,0 +1,45 @@
+From 6b6875cd79f55185122131aa69114bbfa73fca04 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 3e63e4ce45b04..6270b4165644b 100644
+--- a/drivers/slimbus/core.c
++++ b/drivers/slimbus/core.c
+@@ -409,8 +409,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-4.19/smack-handle-smack64transmute-in-smack_inode_setsecu.patch b/queue-4.19/smack-handle-smack64transmute-in-smack_inode_setsecu.patch
new file mode 100644 (file)
index 0000000..19edb3d
--- /dev/null
@@ -0,0 +1,44 @@
+From d2465efe6d8e2d2bad644e9d2b940add3d439278 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 2f2dc49f53dff..d9bff4ba7f2e8 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -2802,6 +2802,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-4.19/smack-set-smack64transmute-only-for-dirs-in-smack_in.patch b/queue-4.19/smack-set-smack64transmute-only-for-dirs-in-smack_in.patch
new file mode 100644 (file)
index 0000000..3aeaee9
--- /dev/null
@@ -0,0 +1,38 @@
+From 9ff6961c77f4e1814ce5a4fa70c000245030c8e2 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 128a5f464740e..2f2dc49f53dff 100644
+--- a/security/smack/smack_lsm.c
++++ b/security/smack/smack_lsm.c
+@@ -1341,7 +1341,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-4.19/soc-fsl-qbman-add-cgr-update-function.patch b/queue-4.19/soc-fsl-qbman-add-cgr-update-function.patch
new file mode 100644 (file)
index 0000000..b92934b
--- /dev/null
@@ -0,0 +1,107 @@
+From 2b6496ce7b74b3e04b8c3ea3b35cc613ae043b48 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 24ca4bedcaa6e..4d0853ead7ddf 100644
+--- a/drivers/soc/fsl/qbman/qman.c
++++ b/drivers/soc/fsl/qbman/qman.c
+@@ -2474,6 +2474,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 597783b8a3a07..b67f2e83bbef9 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-4.19/soc-fsl-qbman-add-helper-for-sanity-checking-cgr-ops.patch b/queue-4.19/soc-fsl-qbman-add-helper-for-sanity-checking-cgr-ops.patch
new file mode 100644 (file)
index 0000000..daa961b
--- /dev/null
@@ -0,0 +1,80 @@
+From cb2aa347c344e691a57955456f3578ad6bd4736f 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 17f72d7ed3103..24ca4bedcaa6e 100644
+--- a/drivers/soc/fsl/qbman/qman.c
++++ b/drivers/soc/fsl/qbman/qman.c
+@@ -2389,13 +2389,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) {
+@@ -2403,10 +2398,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);
+@@ -2434,7 +2444,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-4.19/soc-fsl-qbman-always-disable-interrupts-when-taking-.patch b/queue-4.19/soc-fsl-qbman-always-disable-interrupts-when-taking-.patch
new file mode 100644 (file)
index 0000000..ea407ae
--- /dev/null
@@ -0,0 +1,73 @@
+From e9a20c13617c202253aee022c4eba6e65b9da50c 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 d7bf456fd10e4..17f72d7ed3103 100644
+--- a/drivers/soc/fsl/qbman/qman.c
++++ b/drivers/soc/fsl/qbman/qman.c
+@@ -1369,11 +1369,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;
+@@ -1389,7 +1389,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);
+ }
+@@ -2346,7 +2346,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;
+@@ -2383,7 +2383,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-4.19/soc-fsl-qbman-use-raw-spinlock-for-cgr_lock.patch b/queue-4.19/soc-fsl-qbman-use-raw-spinlock-for-cgr_lock.patch
new file mode 100644 (file)
index 0000000..ef9ed35
--- /dev/null
@@ -0,0 +1,132 @@
+From a3c99cd0f065054849feb567330867ed84ae3021 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 4d0853ead7ddf..ce08ce98142da 100644
+--- a/drivers/soc/fsl/qbman/qman.c
++++ b/drivers/soc/fsl/qbman/qman.c
+@@ -976,7 +976,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];
+@@ -1194,7 +1194,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;
+@@ -1369,11 +1369,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;
+@@ -1389,7 +1392,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);
+ }
+@@ -2346,7 +2349,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;
+@@ -2383,7 +2386,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;
+ }
+@@ -2418,7 +2421,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,
+@@ -2443,7 +2446,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;
+ }
+@@ -2483,9 +2486,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-4.19/sparc-vdso-fix-return-value-of-__setup-handler.patch b/queue-4.19/sparc-vdso-fix-return-value-of-__setup-handler.patch
new file mode 100644 (file)
index 0000000..09a6d3f
--- /dev/null
@@ -0,0 +1,57 @@
+From b886f27b61cda081bda03280525d260e7c630402 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 5eaff3c1aa0c7..1869e4b36db21 100644
+--- a/arch/sparc/vdso/vma.c
++++ b/arch/sparc/vdso/vma.c
+@@ -262,9 +262,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-4.19/sparc64-nmi-watchdog-fix-return-value-of-__setup-han.patch b/queue-4.19/sparc64-nmi-watchdog-fix-return-value-of-__setup-han.patch
new file mode 100644 (file)
index 0000000..6486718
--- /dev/null
@@ -0,0 +1,51 @@
+From 6613e411ca811ece6336f148cbf3901cabac1b5a 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 8babbeb30adf9..1f356928a06d5 100644
+--- a/arch/sparc/kernel/nmi.c
++++ b/arch/sparc/kernel/nmi.c
+@@ -273,7 +273,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-4.19/speakup-fix-8bit-characters-from-direct-synth.patch b/queue-4.19/speakup-fix-8bit-characters-from-direct-synth.patch
new file mode 100644 (file)
index 0000000..f345b2c
--- /dev/null
@@ -0,0 +1,49 @@
+From 845a40f8fe3a542bd9e03e0c28133f3eafef38e5 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-4.19/timer-trace-improve-timer-tracing.patch b/queue-4.19/timer-trace-improve-timer-tracing.patch
new file mode 100644 (file)
index 0000000..2c4a7ed
--- /dev/null
@@ -0,0 +1,129 @@
+From 8f8cbd582e9415845042fec6cb69b310fd4aebf8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Mar 2019 13:09:21 +0100
+Subject: timer/trace: Improve timer tracing
+
+From: Anna-Maria Gleixner <anna-maria@linutronix.de>
+
+[ Upstream commit f28d3d5346e97e60c81f933ac89ccf015430e5cf ]
+
+Timers are added to the timer wheel off by one. This is required in
+case a timer is queued directly before incrementing jiffies to prevent
+early timer expiry.
+
+When reading a timer trace and relying only on the expiry time of the timer
+in the timer_start trace point and on the now in the timer_expiry_entry
+trace point, it seems that the timer fires late. With the current
+timer_expiry_entry trace point information only now=jiffies is printed but
+not the value of base->clk. This makes it impossible to draw a conclusion
+to the index of base->clk and makes it impossible to examine timer problems
+without additional trace points.
+
+Therefore add the base->clk value to the timer_expire_entry trace
+point, to be able to calculate the index the timer base is located at
+during collecting expired timers.
+
+Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: fweisbec@gmail.com
+Cc: peterz@infradead.org
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Link: https://lkml.kernel.org/r/20190321120921.16463-5-anna-maria@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/trace/events/timer.h | 11 +++++++----
+ kernel/time/timer.c          | 17 +++++++++++++----
+ 2 files changed, 20 insertions(+), 8 deletions(-)
+
+diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h
+index 8f6240854e28f..295517f109d71 100644
+--- a/include/trace/events/timer.h
++++ b/include/trace/events/timer.h
+@@ -89,24 +89,27 @@ TRACE_EVENT(timer_start,
+  */
+ TRACE_EVENT(timer_expire_entry,
+-      TP_PROTO(struct timer_list *timer),
++      TP_PROTO(struct timer_list *timer, unsigned long baseclk),
+-      TP_ARGS(timer),
++      TP_ARGS(timer, baseclk),
+       TP_STRUCT__entry(
+               __field( void *,        timer   )
+               __field( unsigned long, now     )
+               __field( void *,        function)
++              __field( unsigned long, baseclk )
+       ),
+       TP_fast_assign(
+               __entry->timer          = timer;
+               __entry->now            = jiffies;
+               __entry->function       = timer->function;
++              __entry->baseclk        = baseclk;
+       ),
+-      TP_printk("timer=%p function=%ps now=%lu",
+-                __entry->timer, __entry->function, __entry->now)
++      TP_printk("timer=%p function=%ps now=%lu baseclk=%lu",
++                __entry->timer, __entry->function, __entry->now,
++                __entry->baseclk)
+ );
+ /**
+diff --git a/kernel/time/timer.c b/kernel/time/timer.c
+index a6e88d9bb931c..140662c2b41e1 100644
+--- a/kernel/time/timer.c
++++ b/kernel/time/timer.c
+@@ -1311,7 +1311,9 @@ int del_timer_sync(struct timer_list *timer)
+ EXPORT_SYMBOL(del_timer_sync);
+ #endif
+-static void call_timer_fn(struct timer_list *timer, void (*fn)(struct timer_list *))
++static void call_timer_fn(struct timer_list *timer,
++                        void (*fn)(struct timer_list *),
++                        unsigned long baseclk)
+ {
+       int count = preempt_count();
+@@ -1334,7 +1336,7 @@ static void call_timer_fn(struct timer_list *timer, void (*fn)(struct timer_list
+        */
+       lock_map_acquire(&lockdep_map);
+-      trace_timer_expire_entry(timer);
++      trace_timer_expire_entry(timer, baseclk);
+       fn(timer);
+       trace_timer_expire_exit(timer);
+@@ -1355,6 +1357,13 @@ static void call_timer_fn(struct timer_list *timer, void (*fn)(struct timer_list
+ static void expire_timers(struct timer_base *base, struct hlist_head *head)
+ {
++      /*
++       * This value is required only for tracing. base->clk was
++       * incremented directly before expire_timers was called. But expiry
++       * is related to the old base->clk value.
++       */
++      unsigned long baseclk = base->clk - 1;
++
+       while (!hlist_empty(head)) {
+               struct timer_list *timer;
+               void (*fn)(struct timer_list *);
+@@ -1368,11 +1377,11 @@ static void expire_timers(struct timer_base *base, struct hlist_head *head)
+               if (timer->flags & TIMER_IRQSAFE) {
+                       raw_spin_unlock(&base->lock);
+-                      call_timer_fn(timer, fn);
++                      call_timer_fn(timer, fn, baseclk);
+                       raw_spin_lock(&base->lock);
+               } else {
+                       raw_spin_unlock_irq(&base->lock);
+-                      call_timer_fn(timer, fn);
++                      call_timer_fn(timer, fn, baseclk);
+                       raw_spin_lock_irq(&base->lock);
+               }
+       }
+-- 
+2.43.0
+
diff --git a/queue-4.19/timer-trace-replace-deprecated-vsprintf-pointer-exte.patch b/queue-4.19/timer-trace-replace-deprecated-vsprintf-pointer-exte.patch
new file mode 100644 (file)
index 0000000..d3916ea
--- /dev/null
@@ -0,0 +1,73 @@
+From 8bb580146d09a5d90cc57d0a5a3e7e4739a93ab6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Mar 2019 13:09:20 +0100
+Subject: timer/trace: Replace deprecated vsprintf pointer extension %pf by %ps
+
+From: Anna-Maria Gleixner <anna-maria@linutronix.de>
+
+[ Upstream commit 6849cbb0f9a8dbc1ba56e9abc6955613103e01e3 ]
+
+Since commit 04b8eb7a4ccd ("symbol lookup: introduce
+dereference_symbol_descriptor()") %pf is deprecated, because %ps is smart
+enough to handle function pointer dereference on platforms where such a
+dereference is required.
+
+While at it add proper line breaks to stay in the 80 character limit.
+
+Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: fweisbec@gmail.com
+Cc: peterz@infradead.org
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Link: https://lkml.kernel.org/r/20190321120921.16463-4-anna-maria@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/trace/events/timer.h | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h
+index 350b046e7576c..8f6240854e28f 100644
+--- a/include/trace/events/timer.h
++++ b/include/trace/events/timer.h
+@@ -73,7 +73,7 @@ TRACE_EVENT(timer_start,
+               __entry->flags          = flags;
+       ),
+-      TP_printk("timer=%p function=%pf expires=%lu [timeout=%ld] cpu=%u idx=%u flags=%s",
++      TP_printk("timer=%p function=%ps expires=%lu [timeout=%ld] cpu=%u idx=%u flags=%s",
+                 __entry->timer, __entry->function, __entry->expires,
+                 (long)__entry->expires - __entry->now,
+                 __entry->flags & TIMER_CPUMASK,
+@@ -105,7 +105,8 @@ TRACE_EVENT(timer_expire_entry,
+               __entry->function       = timer->function;
+       ),
+-      TP_printk("timer=%p function=%pf now=%lu", __entry->timer, __entry->function,__entry->now)
++      TP_printk("timer=%p function=%ps now=%lu",
++                __entry->timer, __entry->function, __entry->now)
+ );
+ /**
+@@ -210,7 +211,7 @@ TRACE_EVENT(hrtimer_start,
+               __entry->mode           = mode;
+       ),
+-      TP_printk("hrtimer=%p function=%pf expires=%llu softexpires=%llu "
++      TP_printk("hrtimer=%p function=%ps expires=%llu softexpires=%llu "
+                 "mode=%s", __entry->hrtimer, __entry->function,
+                 (unsigned long long) __entry->expires,
+                 (unsigned long long) __entry->softexpires,
+@@ -243,7 +244,8 @@ TRACE_EVENT(hrtimer_expire_entry,
+               __entry->function       = hrtimer->function;
+       ),
+-      TP_printk("hrtimer=%p function=%pf now=%llu", __entry->hrtimer, __entry->function,
++      TP_printk("hrtimer=%p function=%ps now=%llu",
++                __entry->hrtimer, __entry->function,
+                 (unsigned long long) __entry->now)
+ );
+-- 
+2.43.0
+
diff --git a/queue-4.19/timers-prepare-support-for-preempt_rt.patch b/queue-4.19/timers-prepare-support-for-preempt_rt.patch
new file mode 100644 (file)
index 0000000..e7fc6d5
--- /dev/null
@@ -0,0 +1,242 @@
+From bdddfba9b9710fbafeec23b4aa82c368d05b2099 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Jul 2019 20:31:00 +0200
+Subject: timers: Prepare support for PREEMPT_RT
+
+From: Anna-Maria Gleixner <anna-maria@linutronix.de>
+
+[ Upstream commit 030dcdd197d77374879bb5603d091eee7d8aba80 ]
+
+When PREEMPT_RT is enabled, the soft interrupt thread can be preempted.  If
+the soft interrupt thread is preempted in the middle of a timer callback,
+then calling del_timer_sync() can lead to two issues:
+
+  - If the caller is on a remote CPU then it has to spin wait for the timer
+    handler to complete. This can result in unbound priority inversion.
+
+  - If the caller originates from the task which preempted the timer
+    handler on the same CPU, then spin waiting for the timer handler to
+    complete is never going to end.
+
+To avoid these issues, add a new lock to the timer base which is held
+around the execution of the timer callbacks. If del_timer_sync() detects
+that the timer callback is currently running, it blocks on the expiry
+lock. When the callback is finished, the expiry lock is dropped by the
+softirq thread which wakes up the waiter and the system makes progress.
+
+This addresses both the priority inversion and the life lock issues.
+
+This mechanism is not used for timers which are marked IRQSAFE as for those
+preemption is disabled accross the callback and therefore this situation
+cannot happen. The callbacks for such timers need to be individually
+audited for RT compliance.
+
+The same issue can happen in virtual machines when the vCPU which runs a
+timer callback is scheduled out. If a second vCPU of the same guest calls
+del_timer_sync() it will spin wait for the other vCPU to be scheduled back
+in. The expiry lock mechanism would avoid that. It'd be trivial to enable
+this when paravirt spinlocks are enabled in a guest, but it's not clear
+whether this is an actual problem in the wild, so for now it's an RT only
+mechanism.
+
+As the softirq thread can be preempted with PREEMPT_RT=y, the SMP variant
+of del_timer_sync() needs to be used on UP as well.
+
+[ tglx: Refactored it for mainline ]
+
+Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20190726185753.832418500@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 |   2 +-
+ kernel/time/timer.c   | 103 ++++++++++++++++++++++++++++++++++++++----
+ 2 files changed, 96 insertions(+), 9 deletions(-)
+
+diff --git a/include/linux/timer.h b/include/linux/timer.h
+index 7b066fd38248b..8e027cb10df01 100644
+--- a/include/linux/timer.h
++++ b/include/linux/timer.h
+@@ -172,7 +172,7 @@ extern void add_timer(struct timer_list *timer);
+ extern int try_to_del_timer_sync(struct timer_list *timer);
+-#ifdef CONFIG_SMP
++#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)
+diff --git a/kernel/time/timer.c b/kernel/time/timer.c
+index 140662c2b41e1..2f5565ed27063 100644
+--- a/kernel/time/timer.c
++++ b/kernel/time/timer.c
+@@ -198,6 +198,10 @@ EXPORT_SYMBOL(jiffies_64);
+ struct timer_base {
+       raw_spinlock_t          lock;
+       struct timer_list       *running_timer;
++#ifdef CONFIG_PREEMPT_RT
++      spinlock_t              expiry_lock;
++      atomic_t                timer_waiters;
++#endif
+       unsigned long           clk;
+       unsigned long           next_expiry;
+       unsigned int            cpu;
+@@ -1245,7 +1249,78 @@ int try_to_del_timer_sync(struct timer_list *timer)
+ }
+ EXPORT_SYMBOL(try_to_del_timer_sync);
+-#ifdef CONFIG_SMP
++#ifdef CONFIG_PREEMPT_RT
++static __init void timer_base_init_expiry_lock(struct timer_base *base)
++{
++      spin_lock_init(&base->expiry_lock);
++}
++
++static inline void timer_base_lock_expiry(struct timer_base *base)
++{
++      spin_lock(&base->expiry_lock);
++}
++
++static inline void timer_base_unlock_expiry(struct timer_base *base)
++{
++      spin_unlock(&base->expiry_lock);
++}
++
++/*
++ * The counterpart to del_timer_wait_running().
++ *
++ * If there is a waiter for base->expiry_lock, then it was waiting for the
++ * timer callback to finish. Drop expiry_lock and reaquire it. That allows
++ * the waiter to acquire the lock and make progress.
++ */
++static void timer_sync_wait_running(struct timer_base *base)
++{
++      if (atomic_read(&base->timer_waiters)) {
++              spin_unlock(&base->expiry_lock);
++              spin_lock(&base->expiry_lock);
++      }
++}
++
++/*
++ * This function is called on PREEMPT_RT kernels when the fast path
++ * deletion of a timer failed because the timer callback function was
++ * running.
++ *
++ * This prevents priority inversion, if the softirq thread on a remote CPU
++ * got preempted, and it prevents a life lock when the task which tries to
++ * delete a timer preempted the softirq thread running the timer callback
++ * function.
++ */
++static void del_timer_wait_running(struct timer_list *timer)
++{
++      u32 tf;
++
++      tf = READ_ONCE(timer->flags);
++      if (!(tf & TIMER_MIGRATING)) {
++              struct timer_base *base = get_timer_base(tf);
++
++              /*
++               * Mark the base as contended and grab the expiry lock,
++               * which is held by the softirq across the timer
++               * callback. Drop the lock immediately so the softirq can
++               * expire the next timer. In theory the timer could already
++               * be running again, but that's more than unlikely and just
++               * causes another wait loop.
++               */
++              atomic_inc(&base->timer_waiters);
++              spin_lock_bh(&base->expiry_lock);
++              atomic_dec(&base->timer_waiters);
++              spin_unlock_bh(&base->expiry_lock);
++      }
++}
++#else
++static inline void timer_base_init_expiry_lock(struct timer_base *base) { }
++static inline void timer_base_lock_expiry(struct timer_base *base) { }
++static inline void timer_base_unlock_expiry(struct timer_base *base) { }
++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
+@@ -1284,6 +1359,8 @@ EXPORT_SYMBOL(try_to_del_timer_sync);
+  */
+ int del_timer_sync(struct timer_list *timer)
+ {
++      int ret;
++
+ #ifdef CONFIG_LOCKDEP
+       unsigned long flags;
+@@ -1301,12 +1378,17 @@ int del_timer_sync(struct timer_list *timer)
+        * could lead to deadlock.
+        */
+       WARN_ON(in_irq() && !(timer->flags & TIMER_IRQSAFE));
+-      for (;;) {
+-              int ret = try_to_del_timer_sync(timer);
+-              if (ret >= 0)
+-                      return ret;
+-              cpu_relax();
+-      }
++
++      do {
++              ret = try_to_del_timer_sync(timer);
++
++              if (unlikely(ret < 0)) {
++                      del_timer_wait_running(timer);
++                      cpu_relax();
++              }
++      } while (ret < 0);
++
++      return ret;
+ }
+ EXPORT_SYMBOL(del_timer_sync);
+ #endif
+@@ -1378,10 +1460,13 @@ static void expire_timers(struct timer_base *base, struct hlist_head *head)
+               if (timer->flags & TIMER_IRQSAFE) {
+                       raw_spin_unlock(&base->lock);
+                       call_timer_fn(timer, fn, baseclk);
++                      base->running_timer = NULL;
+                       raw_spin_lock(&base->lock);
+               } else {
+                       raw_spin_unlock_irq(&base->lock);
+                       call_timer_fn(timer, fn, baseclk);
++                      base->running_timer = NULL;
++                      timer_sync_wait_running(base);
+                       raw_spin_lock_irq(&base->lock);
+               }
+       }
+@@ -1678,6 +1763,7 @@ static inline void __run_timers(struct timer_base *base)
+       if (!time_after_eq(jiffies, base->clk))
+               return;
++      timer_base_lock_expiry(base);
+       raw_spin_lock_irq(&base->lock);
+       /*
+@@ -1704,8 +1790,8 @@ static inline void __run_timers(struct timer_base *base)
+               while (levels--)
+                       expire_timers(base, heads + levels);
+       }
+-      base->running_timer = NULL;
+       raw_spin_unlock_irq(&base->lock);
++      timer_base_unlock_expiry(base);
+ }
+ /*
+@@ -1950,6 +2036,7 @@ static void __init init_timer_cpu(int cpu)
+               base->cpu = cpu;
+               raw_spin_lock_init(&base->lock);
+               base->clk = jiffies;
++              timer_base_init_expiry_lock(base);
+       }
+ }
+-- 
+2.43.0
+
diff --git a/queue-4.19/timers-rename-del_timer_sync-to-timer_delete_sync.patch b/queue-4.19/timers-rename-del_timer_sync-to-timer_delete_sync.patch
new file mode 100644 (file)
index 0000000..6069e87
--- /dev/null
@@ -0,0 +1,130 @@
+From 49bede6456956e527a3245a9f3a3a32c320de5c1 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 a9c20a7ead305..aef40cac2add8 100644
+--- a/include/linux/timer.h
++++ b/include/linux/timer.h
+@@ -171,7 +171,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 489bb01796de4..e3120af29f533 100644
+--- a/kernel/time/timer.c
++++ b/kernel/time/timer.c
+@@ -1037,7 +1037,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.
+                */
+@@ -1216,7 +1216,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.
+@@ -1350,7 +1350,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,
+@@ -1372,10 +1372,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.
+  *
+@@ -1388,7 +1388,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;
+@@ -1421,7 +1421,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 *),
+@@ -1443,8 +1443,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-4.19/timers-update-kernel-doc-for-various-functions.patch b/queue-4.19/timers-update-kernel-doc-for-various-functions.patch
new file mode 100644 (file)
index 0000000..ff8bf44
--- /dev/null
@@ -0,0 +1,265 @@
+From 150c0fe68b670faeaf13c632c944b265c5274d17 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 2f5565ed27063..f63efe259ae46 100644
+--- a/kernel/time/timer.c
++++ b/kernel/time/timer.c
+@@ -1078,14 +1078,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)
+ {
+@@ -1094,24 +1096,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)
+ {
+@@ -1122,11 +1127,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)
+ {
+@@ -1135,18 +1147,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)
+ {
+@@ -1156,11 +1171,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)
+ {
+@@ -1195,15 +1212,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)
+ {
+@@ -1225,10 +1245,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)
+ {
+@@ -1322,23 +1351,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
+  *    ----                             ----
+@@ -1352,10 +1377,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-4.19/timers-use-del_timer_sync-even-on-up.patch b/queue-4.19/timers-use-del_timer_sync-even-on-up.patch
new file mode 100644 (file)
index 0000000..16da958
--- /dev/null
@@ -0,0 +1,80 @@
+From c861b9222b285721ebb64c9c091cd65383823e4c 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 8e027cb10df01..a9c20a7ead305 100644
+--- a/include/linux/timer.h
++++ b/include/linux/timer.h
+@@ -171,12 +171,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 f63efe259ae46..489bb01796de4 100644
+--- a/kernel/time/timer.c
++++ b/kernel/time/timer.c
+@@ -1349,7 +1349,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
+@@ -1423,7 +1422,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-4.19/ubi-check-for-too-small-leb-size-in-vtbl-code.patch b/queue-4.19/ubi-check-for-too-small-leb-size-in-vtbl-code.patch
new file mode 100644 (file)
index 0000000..dd61cfc
--- /dev/null
@@ -0,0 +1,45 @@
+From a1e1d5f3dd021fa82f49c9b5f6308929d60e313a 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 1bc82154bb18f..634ec95a1e71a 100644
+--- a/drivers/mtd/ubi/vtbl.c
++++ b/drivers/mtd/ubi/vtbl.c
+@@ -804,6 +804,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-4.19/ubi-correct-the-calculation-of-fastmap-size.patch b/queue-4.19/ubi-correct-the-calculation-of-fastmap-size.patch
new file mode 100644 (file)
index 0000000..ca98555
--- /dev/null
@@ -0,0 +1,43 @@
+From 88143158954daa536cabbc156ecd22458635903b 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 d45c1d6587d18..e24fc0131d794 100644
+--- a/drivers/mtd/ubi/fastmap.c
++++ b/drivers/mtd/ubi/fastmap.c
+@@ -95,9 +95,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-4.19/ubifs-set-page-uptodate-in-the-correct-place.patch b/queue-4.19/ubifs-set-page-uptodate-in-the-correct-place.patch
new file mode 100644 (file)
index 0000000..eb829d7
--- /dev/null
@@ -0,0 +1,74 @@
+From 705b47602ccec54ef4283d0b596ff02d3c0f264a 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 fca3b7f483c79..e373e5d057fd4 100644
+--- a/fs/ubifs/file.c
++++ b/fs/ubifs/file.c
+@@ -274,9 +274,6 @@ static int write_begin_slow(struct address_space *mapping,
+                               return err;
+                       }
+               }
+-
+-              SetPageUptodate(page);
+-              ClearPageError(page);
+       }
+       if (PagePrivate(page))
+@@ -475,9 +472,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);
+@@ -487,10 +481,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
+@@ -581,6 +573,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-4.19/usb-serial-add-device-id-for-verifone-adapter.patch b/queue-4.19/usb-serial-add-device-id-for-verifone-adapter.patch
new file mode 100644 (file)
index 0000000..d6f4ce2
--- /dev/null
@@ -0,0 +1,94 @@
+From eef55cc6d97d29cd1a98f69ee391635980209bc3 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 b58ca66dc3aed..9901fd79b8a21 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-4.19/usb-serial-cp210x-add-id-for-mgp-instruments-pds100.patch b/queue-4.19/usb-serial-cp210x-add-id-for-mgp-instruments-pds100.patch
new file mode 100644 (file)
index 0000000..7509578
--- /dev/null
@@ -0,0 +1,44 @@
+From 8a71affce8f58ec9dfd5274749015d557bf697e0 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 9901fd79b8a21..4bebe0f3c201a 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-4.19/usb-serial-cp210x-add-pid-vid-for-tdk-nc0110013m-and.patch b/queue-4.19/usb-serial-cp210x-add-pid-vid-for-tdk-nc0110013m-and.patch
new file mode 100644 (file)
index 0000000..efb6745
--- /dev/null
@@ -0,0 +1,36 @@
+From bf78acd4bfed2f8390d612a0f7e7e260504a8608 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 4bebe0f3c201a..4686cf7c6b0a6 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-4.19/usb-serial-ftdi_sio-add-support-for-gmc-z216c-adapte.patch b/queue-4.19/usb-serial-ftdi_sio-add-support-for-gmc-z216c-adapte.patch
new file mode 100644 (file)
index 0000000..8dddbfc
--- /dev/null
@@ -0,0 +1,53 @@
+From 8dbd79ae1abdaa2ef1a3757fc065ed3cda7631e6 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 6d4c572807a41..755cbc9525a1b 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -1045,6 +1045,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-4.19/usb-serial-option-add-meig-smart-slm320-product.patch b/queue-4.19/usb-serial-option-add-meig-smart-slm320-product.patch
new file mode 100644 (file)
index 0000000..3825e94
--- /dev/null
@@ -0,0 +1,85 @@
+From 133b87fab349501bc1e4932160a9c23d4bcf9af2 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 5014f45c7c6a0..7f4baceb540cd 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-4.19/vfio-platform-disable-virqfds-on-cleanup.patch b/queue-4.19/vfio-platform-disable-virqfds-on-cleanup.patch
new file mode 100644 (file)
index 0000000..60934e5
--- /dev/null
@@ -0,0 +1,44 @@
+From 11a2a088bb035db043ab94456c89310282ce5fdc 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 46d4750f43a8d..c53a9b4438733 100644
+--- a/drivers/vfio/platform/vfio_platform_irq.c
++++ b/drivers/vfio/platform/vfio_platform_irq.c
+@@ -329,8 +329,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-4.19/wifi-brcmfmac-fix-use-after-free-bug-in-brcmf_cfg802.patch b/queue-4.19/wifi-brcmfmac-fix-use-after-free-bug-in-brcmf_cfg802.patch
new file mode 100644 (file)
index 0000000..05e91e3
--- /dev/null
@@ -0,0 +1,77 @@
+From 8cacbaf24bcd5d4002ea2ee857ab86f37a984196 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 1827be85f115f..fe8f1134a5f3e 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -690,8 +690,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 */
+@@ -7093,6 +7092,7 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
+       wiphy_unregister(cfg->wiphy);
+       kfree(cfg->ops);
+       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-4.19/x86-cpu-amd-update-the-zenbleed-microcode-revisions.patch b/queue-4.19/x86-cpu-amd-update-the-zenbleed-microcode-revisions.patch
new file mode 100644 (file)
index 0000000..db69270
--- /dev/null
@@ -0,0 +1,44 @@
+From c4fcc0fe81415022653261226c8a2f6e3566a054 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 5b75a4ff6802c..3f6188477e014 100644
+--- a/arch/x86/kernel/cpu/amd.c
++++ b/arch/x86/kernel/cpu/amd.c
+@@ -988,11 +988,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
+