aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSalvatore Bonaccorso <carnil@debian.org>2021-06-30 15:07:41 +0200
committerSalvatore Bonaccorso <carnil@debian.org>2021-06-30 15:36:57 +0200
commit64786232808b4aafaedd4702db095851e7be0a85 (patch)
tree7ef2bd4b46d1f62a12a75f837f5042d1829994c0
parentff825241062a00346f18271297660ffd7954e23b (diff)
downloadkernel_replicant_linux-64786232808b4aafaedd4702db095851e7be0a85.tar.gz
kernel_replicant_linux-64786232808b4aafaedd4702db095851e7be0a85.tar.bz2
kernel_replicant_linux-64786232808b4aafaedd4702db095851e7be0a85.zip
swiotlb: manipulate orig_addr when tlb_addr has offset
Closes: #989778
-rw-r--r--debian/changelog6
-rw-r--r--debian/patches/bugfix/all/swiotlb-manipulate-orig_addr-when-tlb_addr-has-offse.patch128
-rw-r--r--debian/patches/series1
3 files changed, 135 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog
index 089a9692cf5f..39095a13e29c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+linux (5.10.46-2) UNRELEASED; urgency=medium
+
+ * swiotlb: manipulate orig_addr when tlb_addr has offset (Closes: #989778)
+
+ -- Salvatore Bonaccorso <carnil@debian.org> Wed, 30 Jun 2021 15:08:29 +0200
+
linux (5.10.46-1) unstable; urgency=medium
* New upstream stable update:
diff --git a/debian/patches/bugfix/all/swiotlb-manipulate-orig_addr-when-tlb_addr-has-offse.patch b/debian/patches/bugfix/all/swiotlb-manipulate-orig_addr-when-tlb_addr-has-offse.patch
new file mode 100644
index 000000000000..cb3584b82cad
--- /dev/null
+++ b/debian/patches/bugfix/all/swiotlb-manipulate-orig_addr-when-tlb_addr-has-offse.patch
@@ -0,0 +1,128 @@
+From: Bumyong Lee <bumyong.lee@samsung.com>
+Date: Mon, 10 May 2021 18:10:04 +0900
+Subject: swiotlb: manipulate orig_addr when tlb_addr has offset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/commit?id=e6108147dd91b94d1979b110f265710c254c99d5
+Bug-Debian: https://bugs.debian.org/989778
+
+commit 5f89468e2f060031cd89fd4287298e0eaf246bf6 upstream.
+
+in case of driver wants to sync part of ranges with offset,
+swiotlb_tbl_sync_single() copies from orig_addr base to tlb_addr with
+offset and ends up with data mismatch.
+
+It was removed from
+"swiotlb: don't modify orig_addr in swiotlb_tbl_sync_single",
+but said logic has to be added back in.
+
+From Linus's email:
+"That commit which the removed the offset calculation entirely, because the old
+
+ (unsigned long)tlb_addr & (IO_TLB_SIZE - 1)
+
+was wrong, but instead of removing it, I think it should have just
+fixed it to be
+
+ (tlb_addr - mem->start) & (IO_TLB_SIZE - 1);
+
+instead. That way the slot offset always matches the slot index calculation."
+
+(Unfortunatly that broke NVMe).
+
+The use-case that drivers are hitting is as follow:
+
+1. Get dma_addr_t from dma_map_single()
+
+dma_addr_t tlb_addr = dma_map_single(dev, vaddr, vsize, DMA_TO_DEVICE);
+
+ |<---------------vsize------------->|
+ +-----------------------------------+
+ | | original buffer
+ +-----------------------------------+
+ vaddr
+
+ swiotlb_align_offset
+ |<----->|<---------------vsize------------->|
+ +-------+-----------------------------------+
+ | | | swiotlb buffer
+ +-------+-----------------------------------+
+ tlb_addr
+
+2. Do something
+3. Sync dma_addr_t through dma_sync_single_for_device(..)
+
+dma_sync_single_for_device(dev, tlb_addr + offset, size, DMA_TO_DEVICE);
+
+ Error case.
+ Copy data to original buffer but it is from base addr (instead of
+ base addr + offset) in original buffer:
+
+ swiotlb_align_offset
+ |<----->|<- offset ->|<- size ->|
+ +-------+-----------------------------------+
+ | | |##########| | swiotlb buffer
+ +-------+-----------------------------------+
+ tlb_addr
+
+ |<- size ->|
+ +-----------------------------------+
+ |##########| | original buffer
+ +-----------------------------------+
+ vaddr
+
+The fix is to copy the data to the original buffer and take into
+account the offset, like so:
+
+ swiotlb_align_offset
+ |<----->|<- offset ->|<- size ->|
+ +-------+-----------------------------------+
+ | | |##########| | swiotlb buffer
+ +-------+-----------------------------------+
+ tlb_addr
+
+ |<- offset ->|<- size ->|
+ +-----------------------------------+
+ | |##########| | original buffer
+ +-----------------------------------+
+ vaddr
+
+[One fix which was Linus's that made more sense to as it created a
+symmetry would break NVMe. The reason for that is the:
+ unsigned int offset = (tlb_addr - mem->start) & (IO_TLB_SIZE - 1);
+
+would come up with the proper offset, but it would lose the
+alignment (which this patch contains).]
+
+Fixes: 16fc3cef33a0 ("swiotlb: don't modify orig_addr in swiotlb_tbl_sync_single")
+Signed-off-by: Bumyong Lee <bumyong.lee@samsung.com>
+Signed-off-by: Chanho Park <chanho61.park@samsung.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reported-by: Dominique MARTINET <dominique.martinet@atmark-techno.com>
+Reported-by: Horia Geantă <horia.geanta@nxp.com>
+Tested-by: Horia Geantă <horia.geanta@nxp.com>
+CC: stable@vger.kernel.org
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/dma/swiotlb.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
+index 0f61b14b0099..0ed0e1f215c7 100644
+--- a/kernel/dma/swiotlb.c
++++ b/kernel/dma/swiotlb.c
+@@ -667,6 +667,9 @@ void swiotlb_tbl_sync_single(struct device *hwdev, phys_addr_t tlb_addr,
+ if (orig_addr == INVALID_PHYS_ADDR)
+ return;
+
++ orig_addr += (tlb_addr & (IO_TLB_SIZE - 1)) -
++ swiotlb_align_offset(hwdev, orig_addr);
++
+ switch (target) {
+ case SYNC_FOR_CPU:
+ if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL))
+--
+2.32.0
+
diff --git a/debian/patches/series b/debian/patches/series
index af09b317a459..fd30c81d8dcf 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -95,6 +95,7 @@ bugfix/all/partially-revert-usb-kconfig-using-select-for-usb_co.patch
debian/makefile-do-not-check-for-libelf-when-building-oot-module.patch
bugfix/all/partially-revert-net-socket-implement-64-bit-timestamps.patch
bugfix/all/Revert-PCI-PM-Do-not-read-power-state-in-pci_enable_.patch
+bugfix/all/swiotlb-manipulate-orig_addr-when-tlb_addr-has-offse.patch
# Miscellaneous features