From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tom Mingarelli Subject: [PATCH] Intel IOMMU patch to reprocess RMRR info Date: Fri, 15 Jun 2012 08:58:58 -0400 Message-ID: <20120615125336.15536.69372.sendpatchset@localhost6.localdomain6> Return-path: Sender: linux-kernel-owner@vger.kernel.org To: David Woodhouse , Joerg Roedel Cc: Tom Mingarelli , iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org List-Id: iommu@lists.linux-foundation.org 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 Tested-by: Tony Camuso 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 {