As of today, enable_ddw() will return a non-null DMA address if the
created DDW maps the whole partition. If the address is valid,
iommu_bypass_supported_pSeriesLP() will consider iommu bypass enabled.

This can cause some trouble if the DDW happens to start at 0x00.

Instead if checking if the address is non-null, check directly if
the DDW maps the whole partition, so it can bypass iommu.

Signed-off-by: Leonardo Bras <leobra...@gmail.com>
---
 arch/powerpc/platforms/pseries/iommu.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/iommu.c 
b/arch/powerpc/platforms/pseries/iommu.c
index 2d217cda4075..967634a379b0 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -1078,7 +1078,8 @@ static void reset_dma_window(struct pci_dev *dev, struct 
device_node *par_dn)
  *
  * returns the dma offset for use by the direct mapped DMA code.
  */
-static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
+static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn,
+                     bool *maps_partition)
 {
        int len, ret;
        struct ddw_query_response query;
@@ -1237,9 +1238,9 @@ static u64 enable_ddw(struct pci_dev *dev, struct 
device_node *pdn)
        list_add(&window->list, &direct_window_list);
        spin_unlock(&direct_window_list_lock);
 
-       /* Only returns the dma_addr if DDW maps the whole partition */
        if (len == order_base_2(max_addr))
-               dma_addr = be64_to_cpu(ddwprop->dma_base);
+               *maps_partition = true;
+       dma_addr = be64_to_cpu(ddwprop->dma_base);
        goto out_unlock;
 
 out_free_window:
@@ -1324,6 +1325,7 @@ static bool iommu_bypass_supported_pSeriesLP(struct 
pci_dev *pdev, u64 dma_mask)
 {
        struct device_node *dn = pci_device_to_OF_node(pdev), *pdn;
        const __be32 *dma_window = NULL;
+       bool ret = false;
 
        /* only attempt to use a new window if 64-bit DMA is requested */
        if (dma_mask < DMA_BIT_MASK(64))
@@ -1344,13 +1346,10 @@ static bool iommu_bypass_supported_pSeriesLP(struct 
pci_dev *pdev, u64 dma_mask)
                        break;
        }
 
-       if (pdn && PCI_DN(pdn)) {
-               pdev->dev.archdata.dma_offset = enable_ddw(pdev, pdn);
-               if (pdev->dev.archdata.dma_offset)
-                       return true;
-       }
+       if (pdn && PCI_DN(pdn))
+               pdev->dev.archdata.dma_offset = enable_ddw(pdev, pdn, &ret);
 
-       return false;
+       return ret;
 }
 
 static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action,
-- 
2.25.4

Reply via email to