--- /dev/null
+From 968f19c5b1b7d5595423b0ac0020cc18dfed8cb5 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Tue, 4 Feb 2025 13:46:09 +1030
+Subject: btrfs: always fallback to buffered write if the inode requires checksum
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit 968f19c5b1b7d5595423b0ac0020cc18dfed8cb5 upstream.
+
+[BUG]
+It is a long known bug that VM image on btrfs can lead to data csum
+mismatch, if the qemu is using direct-io for the image (this is commonly
+known as cache mode 'none').
+
+[CAUSE]
+Inside the VM, if the fs is EXT4 or XFS, or even NTFS from Windows, the
+fs is allowed to dirty/modify the folio even if the folio is under
+writeback (as long as the address space doesn't have AS_STABLE_WRITES
+flag inherited from the block device).
+
+This is a valid optimization to improve the concurrency, and since these
+filesystems have no extra checksum on data, the content change is not a
+problem at all.
+
+But the final write into the image file is handled by btrfs, which needs
+the content not to be modified during writeback, or the checksum will
+not match the data (checksum is calculated before submitting the bio).
+
+So EXT4/XFS/NTRFS assume they can modify the folio under writeback, but
+btrfs requires no modification, this leads to the false csum mismatch.
+
+This is only a controlled example, there are even cases where
+multi-thread programs can submit a direct IO write, then another thread
+modifies the direct IO buffer for whatever reason.
+
+For such cases, btrfs has no sane way to detect such cases and leads to
+false data csum mismatch.
+
+[FIX]
+I have considered the following ideas to solve the problem:
+
+- Make direct IO to always skip data checksum
+ This not only requires a new incompatible flag, as it breaks the
+ current per-inode NODATASUM flag.
+ But also requires extra handling for no csum found cases.
+
+ And this also reduces our checksum protection.
+
+- Let hardware handle all the checksum
+ AKA, just nodatasum mount option.
+ That requires trust for hardware (which is not that trustful in a lot
+ of cases), and it's not generic at all.
+
+- Always fallback to buffered write if the inode requires checksum
+ This was suggested by Christoph, and is the solution utilized by this
+ patch.
+
+ The cost is obvious, the extra buffer copying into page cache, thus it
+ reduces the performance.
+ But at least it's still user configurable, if the end user still wants
+ the zero-copy performance, just set NODATASUM flag for the inode
+ (which is a common practice for VM images on btrfs).
+
+ Since we cannot trust user space programs to keep the buffer
+ consistent during direct IO, we have no choice but always falling back
+ to buffered IO. At least by this, we avoid the more deadly false data
+ checksum mismatch error.
+
+Suggested-by: Christoph Hellwig <hch@infradead.org>
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/direct-io.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/fs/btrfs/direct-io.c
++++ b/fs/btrfs/direct-io.c
+@@ -868,6 +868,22 @@ relock:
+ btrfs_inode_unlock(BTRFS_I(inode), ilock_flags);
+ goto buffered;
+ }
++ /*
++ * We can't control the folios being passed in, applications can write
++ * to them while a direct IO write is in progress. This means the
++ * content might change after we calculated the data checksum.
++ * Therefore we can end up storing a checksum that doesn't match the
++ * persisted data.
++ *
++ * To be extra safe and avoid false data checksum mismatch, if the
++ * inode requires data checksum, just fallback to buffered IO.
++ * For buffered IO we have full control of page cache and can ensure
++ * no one is modifying the content during writeback.
++ */
++ if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) {
++ btrfs_inode_unlock(BTRFS_I(inode), ilock_flags);
++ goto buffered;
++ }
+
+ /*
+ * The iov_iter can be mapped to the same file range we are writing to.
--- /dev/null
+From e1aa5ef892fb4fa9014a25e87b64b97347919d37 Mon Sep 17 00:00:00 2001
+From: Huacai Chen <chenhuacai@loongson.cn>
+Date: Tue, 3 Feb 2026 14:29:01 +0800
+Subject: net: stmmac: dwmac-loongson: Set clk_csr_i to 100-150MHz
+
+From: Huacai Chen <chenhuacai@loongson.cn>
+
+commit e1aa5ef892fb4fa9014a25e87b64b97347919d37 upstream.
+
+Current clk_csr_i setting of Loongson STMMAC (including LS7A1000/2000
+and LS2K1000/2000/3000) are copy & paste from other drivers. In fact,
+Loongson STMMAC use 125MHz clocks and need 62 freq division to within
+2.5MHz, meeting most PHY MDC requirement. So fix by setting clk_csr_i
+to 100-150MHz, otherwise some PHYs may link fail.
+
+Cc: stable@vger.kernel.org
+Fixes: 30bba69d7db40e7 ("stmmac: pci: Add dwmac support for Loongson")
+Signed-off-by: Hongliang Wang <wanghongliang@loongson.cn>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Link: https://patch.msgid.link/20260203062901.2158236-1-chenhuacai@loongson.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+@@ -86,7 +86,7 @@ static void loongson_default_data(struct
+ /* Get bus_id, this can be overwritten later */
+ plat->bus_id = pci_dev_id(pdev);
+
+- plat->clk_csr = 2; /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */
++ plat->clk_csr = 1; /* clk_csr_i = 100-150MHz & MDC = clk_csr_i/62 */
+ plat->has_gmac = 1;
+ plat->force_sf_dma_mode = 1;
+