linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2 v2] powerpc/powernv: Fix IOMMU group lost
@ 2014-08-06  7:10 Gavin Shan
  2014-08-06  7:10 ` [PATCH 2/2] powerpc/powernv: Remove duplicate check in tce_iommu_bus_notifier() Gavin Shan
  0 siblings, 1 reply; 4+ messages in thread
From: Gavin Shan @ 2014-08-06  7:10 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Gavin Shan, stable

When we take full hotplug to recover from EEH errors, PCI buses
could be involved. For the case, the child devices of involved
PCI buses can't be attached to IOMMU group properly, which is
caused by commit 3f28c5a ("powerpc/powernv: Reduce multi-hit of
iommu_add_device()").

When adding the PCI devices of the newly created PCI buses to
the system, the IOMMU group is expected to be added in (C).
(A) fails to bind the IOMMU group because bus->is_added is
false. (B) fails because the device doesn't have binding IOMMU
table yet. bus->is_added is set to true at end of (C) and
pdev->is_added is set to true at (D).

   pcibios_add_pci_devices()
      pci_scan_bridge()
         pci_scan_child_bus()
            pci_scan_slot()
               pci_scan_single_device()
                  pci_scan_device()
                  pci_device_add()
                     pcibios_add_device()           A: Ignore
                     device_add()                   B: Ignore
                  pcibios_fixup_bus()
                     pcibios_setup_bus_devices()
                        pcibios_setup_device()      C: Hit
      pcibios_finish_adding_to_bus()
         pci_bus_add_devices()
            pci_bus_add_device()                    D: Add device

If the parent PCI bus isn't involved in hotplug, the IOMMU
group is expected to be bound in (B). (A) should fail as the
sysfs entries aren't populated.

The patch fixes the issue by reverting commit 3f28c5a and remove
WARN_ON() in iommu_add_device() to allow calling the function
even the specified device already has associated IOMMU group.

Cc: <stable@vger.kernel.org>  # 3.16+
Reported-by: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Acked-by: Wei Yang <weiyang@linux.vnet.ibm.com>
---
v2: Bail if sysfs entries aren't populated in iommu_add_device()
---
 arch/powerpc/kernel/iommu.c               | 38 +++++++++++++++++--------------
 arch/powerpc/platforms/powernv/pci-ioda.c |  2 +-
 2 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 88e3ec6..48fb2c1 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -1120,37 +1120,41 @@ EXPORT_SYMBOL_GPL(iommu_release_ownership);
 int iommu_add_device(struct device *dev)
 {
 	struct iommu_table *tbl;
-	int ret = 0;
 
-	if (WARN_ON(dev->iommu_group)) {
-		pr_warn("iommu_tce: device %s is already in iommu group %d, skipping\n",
-				dev_name(dev),
-				iommu_group_id(dev->iommu_group));
+	/*
+	 * The sysfs entries should be populated before
+	 * binding IOMMU group. If sysfs entries isn't
+	 * ready, we simply bail.
+	 */
+	if (!device_is_registered(dev))
+		return -ENOENT;
+
+	if (dev->iommu_group) {
+		pr_debug("%s: Skipping device %s with iommu group %d\n",
+			 __func__, dev_name(dev),
+			 iommu_group_id(dev->iommu_group));
 		return -EBUSY;
 	}
 
 	tbl = get_iommu_table_base(dev);
 	if (!tbl || !tbl->it_group) {
-		pr_debug("iommu_tce: skipping device %s with no tbl\n",
-				dev_name(dev));
+		pr_debug("%s: Skipping device %s with no tbl\n",
+			 __func__, dev_name(dev));
 		return 0;
 	}
 
-	pr_debug("iommu_tce: adding %s to iommu group %d\n",
-			dev_name(dev), iommu_group_id(tbl->it_group));
+	pr_debug("%s: Adding %s to iommu group %d\n",
+		 __func__, dev_name(dev),
+		 iommu_group_id(tbl->it_group));
 
 	if (PAGE_SIZE < IOMMU_PAGE_SIZE(tbl)) {
-		pr_err("iommu_tce: unsupported iommu page size.");
-		pr_err("%s has not been added\n", dev_name(dev));
+		pr_err("%s: Invalid IOMMU page size %lx (%lx) on %s\n",
+		       __func__, IOMMU_PAGE_SIZE(tbl),
+		       PAGE_SIZE, dev_name(dev));
 		return -EINVAL;
 	}
 
-	ret = iommu_group_add_device(tbl->it_group, dev);
-	if (ret < 0)
-		pr_err("iommu_tce: %s has not been added, ret=%d\n",
-				dev_name(dev), ret);
-
-	return ret;
+	return iommu_group_add_device(tbl->it_group, dev);
 }
 EXPORT_SYMBOL_GPL(iommu_add_device);
 
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index de19ede..86290eb 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -462,7 +462,7 @@ static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev
 
 	pe = &phb->ioda.pe_array[pdn->pe_number];
 	WARN_ON(get_dma_ops(&pdev->dev) != &dma_iommu_ops);
-	set_iommu_table_base(&pdev->dev, &pe->tce32_table);
+	set_iommu_table_base_and_group(&pdev->dev, &pe->tce32_table);
 }
 
 static int pnv_pci_ioda_dma_set_mask(struct pnv_phb *phb,
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] powerpc/powernv: Remove duplicate check in tce_iommu_bus_notifier()
  2014-08-06  7:10 [PATCH 1/2 v2] powerpc/powernv: Fix IOMMU group lost Gavin Shan
@ 2014-08-06  7:10 ` Gavin Shan
  2014-08-11  3:11   ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 4+ messages in thread
From: Gavin Shan @ 2014-08-06  7:10 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Gavin Shan

The called function iommu_del_device() checks if the device has
attached IOMMU group, we needn't check it again in the parent
function call tce_iommu_bus_notifier().

Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/powernv/pci.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index f91a4e5..b562b0d 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -820,17 +820,18 @@ static int tce_iommu_bus_notifier(struct notifier_block *nb,
 		unsigned long action, void *data)
 {
 	struct device *dev = data;
+	int ret = 0;
 
 	switch (action) {
 	case BUS_NOTIFY_ADD_DEVICE:
-		return iommu_add_device(dev);
+		ret = iommu_add_device(dev);
+		break;
 	case BUS_NOTIFY_DEL_DEVICE:
-		if (dev->iommu_group)
-			iommu_del_device(dev);
-		return 0;
-	default:
-		return 0;
+		iommu_del_device(dev);
+		break;
 	}
+
+	return ret;
 }
 
 static struct notifier_block tce_iommu_bus_nb = {
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 2/2] powerpc/powernv: Remove duplicate check in tce_iommu_bus_notifier()
  2014-08-06  7:10 ` [PATCH 2/2] powerpc/powernv: Remove duplicate check in tce_iommu_bus_notifier() Gavin Shan
@ 2014-08-11  3:11   ` Benjamin Herrenschmidt
  2014-08-11  9:14     ` Gavin Shan
  0 siblings, 1 reply; 4+ messages in thread
From: Benjamin Herrenschmidt @ 2014-08-11  3:11 UTC (permalink / raw)
  To: Gavin Shan; +Cc: linuxppc-dev

On Wed, 2014-08-06 at 17:10 +1000, Gavin Shan wrote:
> The called function iommu_del_device() checks if the device has
> attached IOMMU group, we needn't check it again in the parent
> function call tce_iommu_bus_notifier().

The patch does more than that... it also refactors the function, which
it should either not do or document.

> Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
> ---
>  arch/powerpc/platforms/powernv/pci.c | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
> index f91a4e5..b562b0d 100644
> --- a/arch/powerpc/platforms/powernv/pci.c
> +++ b/arch/powerpc/platforms/powernv/pci.c
> @@ -820,17 +820,18 @@ static int tce_iommu_bus_notifier(struct notifier_block *nb,
>  		unsigned long action, void *data)
>  {
>  	struct device *dev = data;
> +	int ret = 0;
>  
>  	switch (action) {
>  	case BUS_NOTIFY_ADD_DEVICE:
> -		return iommu_add_device(dev);
> +		ret = iommu_add_device(dev);
> +		break;
>  	case BUS_NOTIFY_DEL_DEVICE:
> -		if (dev->iommu_group)
> -			iommu_del_device(dev);
> -		return 0;
> -	default:
> -		return 0;
> +		iommu_del_device(dev);
> +		break;
>  	}
> +
> +	return ret;
>  }
>  
>  static struct notifier_block tce_iommu_bus_nb = {

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 2/2] powerpc/powernv: Remove duplicate check in tce_iommu_bus_notifier()
  2014-08-11  3:11   ` Benjamin Herrenschmidt
@ 2014-08-11  9:14     ` Gavin Shan
  0 siblings, 0 replies; 4+ messages in thread
From: Gavin Shan @ 2014-08-11  9:14 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Gavin Shan

On Mon, Aug 11, 2014 at 01:11:58PM +1000, Benjamin Herrenschmidt wrote:
>On Wed, 2014-08-06 at 17:10 +1000, Gavin Shan wrote:
>> The called function iommu_del_device() checks if the device has
>> attached IOMMU group, we needn't check it again in the parent
>> function call tce_iommu_bus_notifier().
>
>The patch does more than that... it also refactors the function, which
>it should either not do or document.
>

Ben, please drop PATCH[2/2] for now.

Thanks,
Gavin

>> Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
>> ---
>>  arch/powerpc/platforms/powernv/pci.c | 13 +++++++------
>>  1 file changed, 7 insertions(+), 6 deletions(-)
>> 
>> diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
>> index f91a4e5..b562b0d 100644
>> --- a/arch/powerpc/platforms/powernv/pci.c
>> +++ b/arch/powerpc/platforms/powernv/pci.c
>> @@ -820,17 +820,18 @@ static int tce_iommu_bus_notifier(struct notifier_block *nb,
>>  		unsigned long action, void *data)
>>  {
>>  	struct device *dev = data;
>> +	int ret = 0;
>>  
>>  	switch (action) {
>>  	case BUS_NOTIFY_ADD_DEVICE:
>> -		return iommu_add_device(dev);
>> +		ret = iommu_add_device(dev);
>> +		break;
>>  	case BUS_NOTIFY_DEL_DEVICE:
>> -		if (dev->iommu_group)
>> -			iommu_del_device(dev);
>> -		return 0;
>> -	default:
>> -		return 0;
>> +		iommu_del_device(dev);
>> +		break;
>>  	}
>> +
>> +	return ret;
>>  }
>>  
>>  static struct notifier_block tce_iommu_bus_nb = {
>
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-08-11  9:15 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-06  7:10 [PATCH 1/2 v2] powerpc/powernv: Fix IOMMU group lost Gavin Shan
2014-08-06  7:10 ` [PATCH 2/2] powerpc/powernv: Remove duplicate check in tce_iommu_bus_notifier() Gavin Shan
2014-08-11  3:11   ` Benjamin Herrenschmidt
2014-08-11  9:14     ` Gavin Shan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).