ppc64: iommu vmerge fix]
PATCH 1/1 ppc64: iommu vmerge fix]
From: Brian King <[email protected]>
(Looks quite bad, should probably get in right away)
The patch below fixes a bug in the PPC64 iommu vmerge code which results in the potential for iommu_unmap_sg to go off unmapping more than it should. This was found on a test system which resulted in PCI bus errors due to PCI memory being unmapped while DMAs were still in progress.
Signed-off-by Brian King <[email protected]>
Signed-off-by Benjamin Herrenschmidt <[email protected]>
---
linux-2.6-bjking1/arch/ppc64/kernel/iommu.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-)
arch/ppc64/kernel/iommu.c renamed from arch/ppc64/kernel/iommu.c~ppc64_iommu_vmerge_fix +4 -3
@@ -242,7 +242,7 @@ int iommu_map_sg(struct device *dev, strdma_addr_t dma_next =0 , dma_addr;unsigned long flags;struct scatterlist *s, *outs, *segstart; -int outcount; +int outcount, incount;unsigned long handle;BUG_ON (direction ==DMA_NONE );
@@ -252,6 +252,7 @@ int iommu_map_sg(struct device *dev, str outs = s = segstart = &sglist[0 ]; outcount =1 ; + incount = nelems; handle =0 ;/* Init first segment length for backout at failure */
@@ -338,10 +339,10 @@ int iommu_map_sg(struct device *dev, strDBG ("mapped %d elements:\n" , outcount); -/* For the sake of iommu_free_sg, we clear out the length in the +/* For the sake of iommu_unmap_sg, we clear out the length in the * next entry of the sglist if we didn't fill the list completely */ -if (outcount < nelems) { +if (outcount < incount) { outs++; outs->dma_address =DMA_ERROR_CODE ; outs->dma_length =0 ;
_