summaryrefslogtreecommitdiffstats
path: root/drivers/iommu/intel-iommu.c
diff options
context:
space:
mode:
authorLu Baolu <baolu.lu@linux.intel.com>2019-05-25 01:41:32 -0400
committerJoerg Roedel <jroedel@suse.de>2019-05-28 04:19:11 -0400
commit8af46c784ecfe8929f66b5eaae987f6874953226 (patch)
tree6f4bbaec5617602575cb02e97f9c8e32f432da6a /drivers/iommu/intel-iommu.c
parentfa212a97f3a366adcb2046c565e7c978ab067c73 (diff)
iommu/vt-d: Implement is_attach_deferred iommu ops entry
As a domain is now attached to a device earlier, we should implement the is_attach_deferred call-back and use it to defer the domain attach from iommu driver init to device driver init when iommu is pre-enabled in kdump kernel. Suggested-by: Tom Murphy <tmurphy@arista.com> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/intel-iommu.c')
-rw-r--r--drivers/iommu/intel-iommu.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 0bae0b73076c..c8b73802f0e0 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -353,6 +353,8 @@ static void domain_context_clear(struct intel_iommu *iommu,
353static int domain_detach_iommu(struct dmar_domain *domain, 353static int domain_detach_iommu(struct dmar_domain *domain,
354 struct intel_iommu *iommu); 354 struct intel_iommu *iommu);
355static bool device_is_rmrr_locked(struct device *dev); 355static bool device_is_rmrr_locked(struct device *dev);
356static int intel_iommu_attach_device(struct iommu_domain *domain,
357 struct device *dev);
356 358
357#ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON 359#ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON
358int dmar_disabled = 0; 360int dmar_disabled = 0;
@@ -378,6 +380,7 @@ int intel_iommu_gfx_mapped;
378EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped); 380EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
379 381
380#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1)) 382#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
383#define DEFER_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-2))
381static DEFINE_SPINLOCK(device_domain_lock); 384static DEFINE_SPINLOCK(device_domain_lock);
382static LIST_HEAD(device_domain_list); 385static LIST_HEAD(device_domain_list);
383 386
@@ -2408,8 +2411,18 @@ static struct dmar_domain *find_domain(struct device *dev)
2408{ 2411{
2409 struct device_domain_info *info; 2412 struct device_domain_info *info;
2410 2413
2414 if (unlikely(dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO)) {
2415 struct iommu_domain *domain;
2416
2417 dev->archdata.iommu = NULL;
2418 domain = iommu_get_domain_for_dev(dev);
2419 if (domain)
2420 intel_iommu_attach_device(domain, dev);
2421 }
2422
2411 /* No lock here, assumes no domain exit in normal case */ 2423 /* No lock here, assumes no domain exit in normal case */
2412 info = dev->archdata.iommu; 2424 info = dev->archdata.iommu;
2425
2413 if (likely(info)) 2426 if (likely(info))
2414 return info->domain; 2427 return info->domain;
2415 return NULL; 2428 return NULL;
@@ -5504,6 +5517,9 @@ static int intel_iommu_add_device(struct device *dev)
5504 5517
5505 iommu_device_link(&iommu->iommu, dev); 5518 iommu_device_link(&iommu->iommu, dev);
5506 5519
5520 if (translation_pre_enabled(iommu))
5521 dev->archdata.iommu = DEFER_DEVICE_DOMAIN_INFO;
5522
5507 group = iommu_group_get_for_dev(dev); 5523 group = iommu_group_get_for_dev(dev);
5508 5524
5509 if (IS_ERR(group)) 5525 if (IS_ERR(group))
@@ -5828,6 +5844,12 @@ intel_iommu_aux_get_pasid(struct iommu_domain *domain, struct device *dev)
5828 dmar_domain->default_pasid : -EINVAL; 5844 dmar_domain->default_pasid : -EINVAL;
5829} 5845}
5830 5846
5847static bool intel_iommu_is_attach_deferred(struct iommu_domain *domain,
5848 struct device *dev)
5849{
5850 return dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO;
5851}
5852
5831const struct iommu_ops intel_iommu_ops = { 5853const struct iommu_ops intel_iommu_ops = {
5832 .capable = intel_iommu_capable, 5854 .capable = intel_iommu_capable,
5833 .domain_alloc = intel_iommu_domain_alloc, 5855 .domain_alloc = intel_iommu_domain_alloc,
@@ -5850,6 +5872,7 @@ const struct iommu_ops intel_iommu_ops = {
5850 .dev_feat_enabled = intel_iommu_dev_feat_enabled, 5872 .dev_feat_enabled = intel_iommu_dev_feat_enabled,
5851 .dev_enable_feat = intel_iommu_dev_enable_feat, 5873 .dev_enable_feat = intel_iommu_dev_enable_feat,
5852 .dev_disable_feat = intel_iommu_dev_disable_feat, 5874 .dev_disable_feat = intel_iommu_dev_disable_feat,
5875 .is_attach_deferred = intel_iommu_is_attach_deferred,
5853 .pgsize_bitmap = INTEL_IOMMU_PGSIZES, 5876 .pgsize_bitmap = INTEL_IOMMU_PGSIZES,
5854}; 5877};
5855 5878