diff options
Diffstat (limited to 'drivers/iommu/intel-iommu.c')
-rw-r--r-- | drivers/iommu/intel-iommu.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 9476c1b96090..c2c07a4a7f21 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -2327,8 +2327,39 @@ static int domain_add_dev_info(struct dmar_domain *domain, | |||
2327 | return 0; | 2327 | return 0; |
2328 | } | 2328 | } |
2329 | 2329 | ||
2330 | static bool device_has_rmrr(struct pci_dev *dev) | ||
2331 | { | ||
2332 | struct dmar_rmrr_unit *rmrr; | ||
2333 | int i; | ||
2334 | |||
2335 | for_each_rmrr_units(rmrr) { | ||
2336 | for (i = 0; i < rmrr->devices_cnt; i++) { | ||
2337 | /* | ||
2338 | * Return TRUE if this RMRR contains the device that | ||
2339 | * is passed in. | ||
2340 | */ | ||
2341 | if (rmrr->devices[i] == dev) | ||
2342 | return true; | ||
2343 | } | ||
2344 | } | ||
2345 | return false; | ||
2346 | } | ||
2347 | |||
2330 | static int iommu_should_identity_map(struct pci_dev *pdev, int startup) | 2348 | static int iommu_should_identity_map(struct pci_dev *pdev, int startup) |
2331 | { | 2349 | { |
2350 | |||
2351 | /* | ||
2352 | * We want to prevent any device associated with an RMRR from | ||
2353 | * getting placed into the SI Domain. This is done because | ||
2354 | * problems exist when devices are moved in and out of domains | ||
2355 | * and their respective RMRR info is lost. We exempt USB devices | ||
2356 | * from this process due to their usage of RMRRs that are known | ||
2357 | * to not be needed after BIOS hand-off to OS. | ||
2358 | */ | ||
2359 | if (device_has_rmrr(pdev) && | ||
2360 | (pdev->class >> 8) != PCI_CLASS_SERIAL_USB) | ||
2361 | return 0; | ||
2362 | |||
2332 | if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev)) | 2363 | if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev)) |
2333 | return 1; | 2364 | return 1; |
2334 | 2365 | ||