[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200624062411.367796-7-leobras.c@gmail.com>
Date: Wed, 24 Jun 2020 03:24:11 -0300
From: Leonardo Bras <leobras.c@...il.com>
To: Michael Ellerman <mpe@...erman.id.au>,
Benjamin Herrenschmidt <benh@...nel.crashing.org>,
Paul Mackerras <paulus@...ba.org>,
Leonardo Bras <leobras.c@...il.com>,
Alexey Kardashevskiy <aik@...abs.ru>,
Thiago Jung Bauermann <bauerman@...ux.ibm.com>,
Ram Pai <linuxram@...ibm.com>
Cc: linuxppc-dev@...ts.ozlabs.org, linux-kernel@...r.kernel.org
Subject: [PATCH v2 6/6] powerpc/pseries/iommu: Avoid errors when DDW starts at 0x00
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 <leobras.c@...il.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
Powered by blists - more mailing lists