This patch is being submitted to handle the case where a pci device is
placed into the si domain, but then removed. The RMRR information for
such devices need to be re-processed to avoid DMA Read errors due to
the Present Bit being cleared in the context entry.
----
drivers/iommu/intel-iommu.c |   32 ++++++++++++++++++++++++++++++++
1 files changed, 32 insertions(+), 0 deletions(-)
    
Signed-off-by: Tom Mingarelli <[email protected]>
Tested-by: Tony Camuso <[email protected]>

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index f93d5ac..5ae57c5 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2696,6 +2696,37 @@ static int iommu_dummy(struct pci_dev *pdev)
        return pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO;
 }
 
+static int reprocess_rmrr(struct device *dev)
+{
+       struct dmar_rmrr_unit *rmrr;
+       struct pci_dev *pdev;
+       int i, ret;
+
+       pdev = to_pci_dev(dev);
+
+       for_each_rmrr_units(rmrr) {
+               for (i = 0; i < rmrr->devices_cnt; i++) {
+                       /*
+                        * Here we are just concerned with
+                        * finding the one device that was
+                        * removed from the si_domain and
+                        * re-evaluating its RMRR info.
+                        */
+                       if (rmrr->devices[i] != pdev)
+                               continue;
+                       pr_info("%s %s\n",
+                               "IOMMU: Reprocess RMRR information for device",
+                               pci_name(pdev));
+                       ret = iommu_prepare_rmrr_dev(rmrr, pdev);
+                       if (ret)
+                               pr_err("%s %s\n",
+                                       "IOMMU: Reprocessing RMRR reserved",
+                                       "region for device failed");
+               }
+       }
+       return 0;
+}
+
 /* Check if the pdev needs to go through non-identity map and unmap process.*/
 static int iommu_no_mapping(struct device *dev)
 {
@@ -2724,6 +2755,7 @@ static int iommu_no_mapping(struct device *dev)
                        domain_remove_one_dev_info(si_domain, pdev);
                        printk(KERN_INFO "32bit %s uses non-identity mapping\n",
                               pci_name(pdev));
+                       reprocess_rmrr(dev);
                        return 0;
                }
        } else {
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to