intel-iommu: Check for identity mapping candidate using system dma mask
The identity mapping code appears to make the assumption that if the devices dma_mask is greater than 32bits the device can use identity mapping. But that is not true: take the case where we have a 40bit device in a 44bit architecture. The device can potentially receive a physical address that it will truncate and cause incorrect addresses to be used. Instead check to see if the device's dma_mask is large enough to address the system's dma_mask. Signed-off-by: Mike Travis <travis@sgi.com> Reviewed-by: Mike Habeck <habeck@sgi.com> Cc: stable@kernel.org Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
This commit is contained in:
parent
9b4554b21e
commit
8fcc5372fb
|
@ -2316,8 +2316,19 @@ static int iommu_should_identity_map(struct pci_dev *pdev, int startup)
|
|||
* Assume that they will -- if they turn out not to be, then we can
|
||||
* take them out of the 1:1 domain later.
|
||||
*/
|
||||
if (!startup)
|
||||
return pdev->dma_mask > DMA_BIT_MASK(32);
|
||||
if (!startup) {
|
||||
/*
|
||||
* If the device's dma_mask is less than the system's memory
|
||||
* size then this is not a candidate for identity mapping.
|
||||
*/
|
||||
u64 dma_mask = pdev->dma_mask;
|
||||
|
||||
if (pdev->dev.coherent_dma_mask &&
|
||||
pdev->dev.coherent_dma_mask < dma_mask)
|
||||
dma_mask = pdev->dev.coherent_dma_mask;
|
||||
|
||||
return dma_mask >= dma_get_required_mask(&pdev->dev);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue