diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/intel-iommu.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 7fe5f7920caf..1840a0578a42 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -3215,6 +3215,33 @@ static int __init init_iommu_sysfs(void) | |||
3215 | } | 3215 | } |
3216 | #endif /* CONFIG_PM */ | 3216 | #endif /* CONFIG_PM */ |
3217 | 3217 | ||
3218 | /* | ||
3219 | * Here we only respond to action of unbound device from driver. | ||
3220 | * | ||
3221 | * Added device is not attached to its DMAR domain here yet. That will happen | ||
3222 | * when mapping the device to iova. | ||
3223 | */ | ||
3224 | static int device_notifier(struct notifier_block *nb, | ||
3225 | unsigned long action, void *data) | ||
3226 | { | ||
3227 | struct device *dev = data; | ||
3228 | struct pci_dev *pdev = to_pci_dev(dev); | ||
3229 | struct dmar_domain *domain; | ||
3230 | |||
3231 | domain = find_domain(pdev); | ||
3232 | if (!domain) | ||
3233 | return 0; | ||
3234 | |||
3235 | if (action == BUS_NOTIFY_UNBOUND_DRIVER && !iommu_pass_through) | ||
3236 | domain_remove_one_dev_info(domain, pdev); | ||
3237 | |||
3238 | return 0; | ||
3239 | } | ||
3240 | |||
3241 | static struct notifier_block device_nb = { | ||
3242 | .notifier_call = device_notifier, | ||
3243 | }; | ||
3244 | |||
3218 | int __init intel_iommu_init(void) | 3245 | int __init intel_iommu_init(void) |
3219 | { | 3246 | { |
3220 | int ret = 0; | 3247 | int ret = 0; |
@@ -3267,6 +3294,8 @@ int __init intel_iommu_init(void) | |||
3267 | 3294 | ||
3268 | register_iommu(&intel_iommu_ops); | 3295 | register_iommu(&intel_iommu_ops); |
3269 | 3296 | ||
3297 | bus_register_notifier(&pci_bus_type, &device_nb); | ||
3298 | |||
3270 | return 0; | 3299 | return 0; |
3271 | } | 3300 | } |
3272 | 3301 | ||