Commit 8fd2ed1c authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'stable/for-linus-5.14' of...

Merge branch 'stable/for-linus-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb

Pull swiotlb fix from Konrad Rzeszutek Wilk:
 "A fix for the regression for the DMA operations where the offset was
  ignored and corruptions would appear.

  Going forward there will be a cleanups to make the offset and
  alignment logic more clearer and better test-cases to help with this"

* 'stable/for-linus-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb:
  swiotlb: manipulate orig_addr when tlb_addr has offset
parents 0c18f29a 5f89468e
...@@ -334,6 +334,14 @@ void __init swiotlb_exit(void) ...@@ -334,6 +334,14 @@ void __init swiotlb_exit(void)
io_tlb_default_mem = NULL; io_tlb_default_mem = NULL;
} }
/*
* Return the offset into a iotlb slot required to keep the device happy.
*/
static unsigned int swiotlb_align_offset(struct device *dev, u64 addr)
{
return addr & dma_get_min_align_mask(dev) & (IO_TLB_SIZE - 1);
}
/* /*
* Bounce: copy the swiotlb buffer from or back to the original dma location * Bounce: copy the swiotlb buffer from or back to the original dma location
*/ */
...@@ -346,10 +354,17 @@ static void swiotlb_bounce(struct device *dev, phys_addr_t tlb_addr, size_t size ...@@ -346,10 +354,17 @@ static void swiotlb_bounce(struct device *dev, phys_addr_t tlb_addr, size_t size
size_t alloc_size = mem->slots[index].alloc_size; size_t alloc_size = mem->slots[index].alloc_size;
unsigned long pfn = PFN_DOWN(orig_addr); unsigned long pfn = PFN_DOWN(orig_addr);
unsigned char *vaddr = phys_to_virt(tlb_addr); unsigned char *vaddr = phys_to_virt(tlb_addr);
unsigned int tlb_offset;
if (orig_addr == INVALID_PHYS_ADDR) if (orig_addr == INVALID_PHYS_ADDR)
return; return;
tlb_offset = (tlb_addr & (IO_TLB_SIZE - 1)) -
swiotlb_align_offset(dev, orig_addr);
orig_addr += tlb_offset;
alloc_size -= tlb_offset;
if (size > alloc_size) { if (size > alloc_size) {
dev_WARN_ONCE(dev, 1, dev_WARN_ONCE(dev, 1,
"Buffer overflow detected. Allocation size: %zu. Mapping size: %zu.\n", "Buffer overflow detected. Allocation size: %zu. Mapping size: %zu.\n",
...@@ -390,14 +405,6 @@ static void swiotlb_bounce(struct device *dev, phys_addr_t tlb_addr, size_t size ...@@ -390,14 +405,6 @@ static void swiotlb_bounce(struct device *dev, phys_addr_t tlb_addr, size_t size
#define slot_addr(start, idx) ((start) + ((idx) << IO_TLB_SHIFT)) #define slot_addr(start, idx) ((start) + ((idx) << IO_TLB_SHIFT))
/*
* Return the offset into a iotlb slot required to keep the device happy.
*/
static unsigned int swiotlb_align_offset(struct device *dev, u64 addr)
{
return addr & dma_get_min_align_mask(dev) & (IO_TLB_SIZE - 1);
}
/* /*
* Carefully handle integer overflow which can occur when boundary_mask == ~0UL. * Carefully handle integer overflow which can occur when boundary_mask == ~0UL.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment