Patch "s390/pci: fix dma address calculation in map_sg" has been added to the 4.9-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
s390/pci: fix dma address calculation in map_sg
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
s390-pci-fix-dma-address-calculation-in-map_sg.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
6b7df3ce92ac82ec3f4a2953b6fed77da7b38aaaMon Sep 17 00:00:00 2001
From: Sebastian Ott <[email protected]>
Date: Mon, 7 Nov 2016 15:06:03 +0100
Subject: s390/pci: fix dma address calculation in map_sg
From: Sebastian Ott <[email protected]>
commit 6b7df3ce92ac82ec3f4a2953b6fed77da7b38aaa upstream.
__s390_dma_map_sg maps a dma-contiguous area. Although we only map whole pages we have to take into account that the area doesn't start or stop at a page boundary because we use the dma address to loop over the individual sg entries. Failing to do that might lead to an access of the wrong sg entry.
--- arch/s390/pci/pci_dma.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
arch/s390/pci/pci_dma.c +8 -7
@@ -419,6 +419,7 @@ static int __s390_dma_map_sg(struct devi size_t size, dma_addr_t *handle, enum dma_data_direction dir) { + unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;struct zpci_dev *zdev =to_zpci (to_pci_dev (dev));dma_addr_t dma_addr_base, dma_addr;int flags =ZPCI_PTE_VALID ;
@@ -426,8 +427,7 @@ static int __s390_dma_map_sg(struct deviunsigned long pa =0 ;int ret; - size =PAGE_ALIGN (size); - dma_addr_base =dma_alloc_address (dev, size >>PAGE_SHIFT ); + dma_addr_base =dma_alloc_address (dev, nr_pages);if (dma_addr_base ==DMA_ERROR_CODE )return -ENOMEM ;
@@ -436,26 +436,27 @@ static int __s390_dma_map_sg(struct devi flags |=ZPCI_TABLE_PROTECTED ;for (s = sg; dma_addr < dma_addr_base + size; s =sg_next (s)) { - pa =page_to_phys (sg_page (s)) + s->offset; - ret =__dma_update_trans (zdev, pa, dma_addr, s->length, flags); + pa =page_to_phys (sg_page (s)); + ret =__dma_update_trans (zdev, pa, dma_addr, + s->offset + s->length, flags);if (ret) goto unmap; - dma_addr += s->length; + dma_addr += s->offset + s->length; } ret =__dma_purge_tlb (zdev, dma_addr_base, size, flags);if (ret) goto unmap; *handle = dma_addr_base; -atomic64_add (size >>PAGE_SHIFT , &zdev->mapped_pages); +atomic64_add (nr_pages, &zdev->mapped_pages);return ret; unmap:dma_update_trans (zdev,0 , dma_addr_base, dma_addr - dma_addr_base,ZPCI_PTE_INVALID ); -dma_free_address (dev, dma_addr_base, size >>PAGE_SHIFT ); +dma_free_address (dev, dma_addr_base, nr_pages);zpci_err ("map error:\n" );zpci_err_dma (ret, pa);return ret;
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/s390-pci-fix-dma-address-calculation-in-map_sg.patch