[PATCH] SCSI: amd_iommu dma_boundary overflow

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

For a 64-bit DMA capable PCIe storage HBA running under the 64-bit
AMD-VI IOMMU environment, the amd_iommu code was observed to hit an
overflow when it tries to page align the dma_parms->segment_boundary_mask.
This overflow would eventually trigger the BUG_ON in the iommu-helper's
iommu_is_span_boundary is_power_of_2 check.

A little back tracking shows that since the device is 64-bit DMA capable,
the pcidev->dma_mask was correctly set to DMA_BIT_MASK(64).  This dma_mask
was then transferred to the SCSI host's dma_boundary param (by the iSCSI
driver) and was eventually used to populate the q->limits.seg_boundary_mask
(via blk_queue_segment_boundary) and the dma_parms->segment_boundary_mask
(via dma_set_seg_boundary) during the scsi queue allocation.

The code seems correct as it make sense to impose the same hardware
segment boundary limit on both the blk queue and the DMA code.  It would
be an easy alternative to simply prevent the shost->dma_boundary from
being set to DMA_BIT_MASK(64), but it seems more correct to fix the
amd_iommu code itself to detect and handle this max 64-bit mask condition.

Please let me know your comments.

Thanks,
Eddie

Signed-off-by: Eddie Wai <eddie.wai@xxxxxxxxxxxx>
---
 drivers/iommu/amd_iommu.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index d90a421..63185a1 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -1526,11 +1526,14 @@ static unsigned long dma_ops_area_alloc(struct device *dev,
 	unsigned long boundary_size;
 	unsigned long address = -1;
 	unsigned long limit;
+	unsigned long mask;
 
 	next_bit >>= PAGE_SHIFT;
 
-	boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
-			PAGE_SIZE) >> PAGE_SHIFT;
+	mask = dma_get_seg_boundary(dev);
+	boundary_size = mask + 1 ?
+			ALIGN(mask + 1, PAGE_SIZE) >> PAGE_SHIFT :
+			1UL << (BITS_PER_LONG - PAGE_SHIFT);
 
 	for (;i < max_index; ++i) {
 		unsigned long offset = dom->aperture[i]->offset >> PAGE_SHIFT;
-- 
1.7.7.4


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux