Patchwork pseries/iommu: restore iommu table pointer when restoring iommu ops

login
register
mail settings
Submitter Nishanth Aravamudan
Date May 9, 2011, 10:58 p.m.
Message ID <1304981883-18796-1-git-send-email-nacc@us.ibm.com>
Download mbox | patch
Permalink /patch/94909/
State Accepted
Commit eb0dd411bd90dd5ad3f1936930d3e83d9ef95561
Delegated to: Benjamin Herrenschmidt
Headers show

Comments

Nishanth Aravamudan - May 9, 2011, 10:58 p.m.
When we swtich to direct dma ops, we set the dma data union to have the
dma offset.  When we switch back to iommu table ops because of a later
dma_set_mask, we need to restore the iommu table pointer. Without this
change, crashes have been observed on kexec where (for reasons still
being investigated) we fall back to a 32-bit dma mask on a particular
device and then panic because the table pointer is not valid.

The easiset way to find this value is to call
pci_dma_dev_setup_pSeriesLP which will search up the pci tree until it
finds the node with the table.

Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
Cc: Milton Miller <miltonm@bga.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Anton Blanchard <anton@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org

---
 arch/powerpc/platforms/pseries/iommu.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

Patch

diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index f66c6b6..a3ee4e7 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -1036,10 +1036,10 @@  static int dma_set_mask_pSeriesLP(struct device *dev, u64 dma_mask)
 	if (!dev->dma_mask || !dma_supported(dev, dma_mask))
 		return -EIO;
 
+	pdev = to_pci_dev(dev);
+
 	/* only attempt to use a new window if 64-bit DMA is requested */
 	if (!disable_ddw && dma_mask == DMA_BIT_MASK(64)) {
-		pdev = to_pci_dev(dev);
-
 		dn = pci_device_to_OF_node(pdev);
 		dev_dbg(dev, "node is %s\n", dn->full_name);
 
@@ -1070,6 +1070,7 @@  static int dma_set_mask_pSeriesLP(struct device *dev, u64 dma_mask)
 	if (!ddw_enabled) {
 		dev_info(dev, "Using 32-bit DMA via iommu\n");
 		set_dma_ops(dev, &dma_iommu_ops);
+		pci_dma_dev_setup_pSeriesLP(pdev);
 	}
 
 	*dev->dma_mask = dma_mask;