All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gavin Shan <gwshan@linux.vnet.ibm.com>
To: Gavin Shan <gwshan@linux.vnet.ibm.com>
Cc: linuxppc-dev@lists.ozlabs.org
Subject: Re: [RFC PATCH] powerpc/powernv: Fix dma_ops for bypass window
Date: Thu, 25 Sep 2014 16:03:36 +1000	[thread overview]
Message-ID: <20140925060336.GA16735@shangw> (raw)
In-Reply-To: <1411618460-8153-1-git-send-email-gwshan@linux.vnet.ibm.com>

On Thu, Sep 25, 2014 at 02:14:20PM +1000, Gavin Shan wrote:

Please ignore this. I was told by Ben some drivers don't call
set_dev_mask(). So I have to fix it in another way.

Thanks,
Gavin

>When using bypass window on IODA2, the incorrect DMA operations
>"dma_iommu_ops" is used by devices. The device driver calls
>dma_get_required_mask() to determine using 32-bits or bypass DMA
>window. Unfortunately, the returned DMA mask always forces the
>driver to use 32-bits DMA window. The problem was reported on
>the device as follows:
>
>0004:03:00.0 0107: 1000:0087 (rev 05)
>0004:03:00.0 Serial Attached SCSI controller: LSI Logic / Symbios \
>             Logic SAS2308 PCI-Express Fusion-MPT SAS-2 (rev 05)
>
>The patch fixes above issue by keeping things consistent: when
>enabling bypass window, we switch to "dma_direct_ops". Instead,
>switch to "pci_dma_ops" when disabling bypass window.
>
>Reported-by: Murali N. Iyer <mniyer@us.ibm.com>
>Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
>---
> arch/powerpc/platforms/powernv/pci-ioda.c | 76 +++++++++++++++++++------------
> 1 file changed, 46 insertions(+), 30 deletions(-)
>
>diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
>index 36b1a7a..60e44d9 100644
>--- a/arch/powerpc/platforms/powernv/pci-ioda.c
>+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
>@@ -883,13 +883,29 @@ static int pnv_pci_ioda_dma_set_mask(struct pnv_phb *phb,
> 		set_dma_offset(&pdev->dev, pe->tce_bypass_base);
> 	} else {
> 		dev_info(&pdev->dev, "Using 32-bit DMA via iommu\n");
>-		set_dma_ops(&pdev->dev, &dma_iommu_ops);
>+		set_dma_ops(&pdev->dev, get_pci_dma_ops());
> 		set_iommu_table_base(&pdev->dev, &pe->tce32_table);
> 	}
> 	*pdev->dev.dma_mask = dma_mask;
> 	return 0;
> }
>
>+static void pnv_ioda_setup_dev_dma(struct pnv_ioda_pe *pe,
>+				   struct pci_dev *pdev,
>+				   bool add_to_iommu_group)
>+{
>+	if (pe->tce_bypass_enabled) {
>+		set_dma_ops(&pdev->dev, &dma_direct_ops);
>+		set_dma_offset(&pdev->dev, pe->tce_bypass_base);
>+	} else {
>+		set_dma_ops(&pdev->dev, get_pci_dma_ops());
>+		set_iommu_table_base(&pdev->dev, &pe->tce32_table);
>+	}
>+
>+	if (add_to_iommu_group)
>+		iommu_add_device(&pdev->dev);
>+}
>+
> static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe,
> 				   struct pci_bus *bus,
> 				   bool add_to_iommu_group)
>@@ -897,11 +913,7 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe,
> 	struct pci_dev *dev;
>
> 	list_for_each_entry(dev, &bus->devices, bus_list) {
>-		if (add_to_iommu_group)
>-			set_iommu_table_base_and_group(&dev->dev,
>-						       &pe->tce32_table);
>-		else
>-			set_iommu_table_base(&dev->dev, &pe->tce32_table);
>+		pnv_ioda_setup_dev_dma(pe, dev, add_to_iommu_group);
>
> 		if (dev->subordinate)
> 			pnv_ioda_setup_bus_dma(pe, dev->subordinate,
>@@ -909,6 +921,15 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe,
> 	}
> }
>
>+static void pnv_ioda_setup_pe_dma(struct pnv_ioda_pe *pe,
>+				  bool add_to_iommu_group)
>+{
>+	if (pe->pdev)
>+		pnv_ioda_setup_dev_dma(pe, pe->pdev, add_to_iommu_group);
>+	else
>+		pnv_ioda_setup_bus_dma(pe, pe->pbus, add_to_iommu_group);
>+}
>+
> static void pnv_pci_ioda1_tce_invalidate(struct pnv_ioda_pe *pe,
> 					 struct iommu_table *tbl,
> 					 __be64 *startp, __be64 *endp, bool rm)
>@@ -1080,11 +1101,7 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
> 	iommu_init_table(tbl, phb->hose->node);
> 	iommu_register_group(tbl, phb->hose->global_number, pe->pe_number);
>
>-	if (pe->pdev)
>-		set_iommu_table_base_and_group(&pe->pdev->dev, tbl);
>-	else
>-		pnv_ioda_setup_bus_dma(pe, pe->pbus, true);
>-
>+	pnv_ioda_setup_pe_dma(pe, true);
> 	return;
>  fail:
> 	/* XXX Failure: Try to fallback to 64-bit only ? */
>@@ -1101,7 +1118,13 @@ static void pnv_pci_ioda2_set_bypass(struct iommu_table *tbl, bool enable)
> 	uint16_t window_id = (pe->pe_number << 1 ) + 1;
> 	int64_t rc;
>
>+	/* Check if we really need do something */
>+	if (pe->tce_bypass_enabled == enable)
>+		return;
>+
> 	pe_info(pe, "%sabling 64-bit DMA bypass\n", enable ? "En" : "Dis");
>+	pe->tce_bypass_enabled = enable;
>+
> 	if (enable) {
> 		phys_addr_t top = memblock_end_of_DRAM();
>
>@@ -1117,22 +1140,15 @@ static void pnv_pci_ioda2_set_bypass(struct iommu_table *tbl, bool enable)
> 						     window_id,
> 						     pe->tce_bypass_base,
> 						     0);
>-
>-		/*
>-		 * EEH needs the mapping between IOMMU table and group
>-		 * of those VFIO/KVM pass-through devices. We can postpone
>-		 * resetting DMA ops until the DMA mask is configured in
>-		 * host side.
>-		 */
>-		if (pe->pdev)
>-			set_iommu_table_base(&pe->pdev->dev, tbl);
>-		else
>-			pnv_ioda_setup_bus_dma(pe, pe->pbus, false);
> 	}
>-	if (rc)
>+	if (rc != OPAL_SUCCESS) {
> 		pe_err(pe, "OPAL error %lld configuring bypass window\n", rc);
>-	else
>-		pe->tce_bypass_enabled = enable;
>+		return;
>+	}
>+
>+	/* Update base and operations */
>+	pe->tce_bypass_enabled = enable;
>+	pnv_ioda_setup_pe_dma(pe, false);
> }
>
> static void pnv_pci_ioda2_setup_bypass_pe(struct pnv_phb *phb,
>@@ -1213,12 +1229,12 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb,
> 	iommu_init_table(tbl, phb->hose->node);
> 	iommu_register_group(tbl, phb->hose->global_number, pe->pe_number);
>
>-	if (pe->pdev)
>-		set_iommu_table_base_and_group(&pe->pdev->dev, tbl);
>-	else
>-		pnv_ioda_setup_bus_dma(pe, pe->pbus, true);
>+	/* If the bypass window fails to be created, we still
>+	 * can use 32-bits window.
>+	 */
>+	pnv_ioda_setup_pe_dma(pe, true);
>
>-	/* Also create a bypass window */
>+	/* Create bypass window */
> 	pnv_pci_ioda2_setup_bypass_pe(phb, pe);
> 	return;
> fail:
>-- 
>1.8.3.2
>

      reply	other threads:[~2014-09-25  6:04 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-25  4:14 [RFC PATCH] powerpc/powernv: Fix dma_ops for bypass window Gavin Shan
2014-09-25  6:03 ` Gavin Shan [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140925060336.GA16735@shangw \
    --to=gwshan@linux.vnet.ibm.com \
    --cc=linuxppc-dev@lists.ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.