diff options
| -rw-r--r-- | drivers/pci/intel-iommu.c | 31 | 
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 3f9a891..ae762ec 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -2289,8 +2289,39 @@ static int domain_add_dev_info(struct dmar_domain *domain,  	return 0;  } +static bool device_has_rmrr(struct pci_dev *dev) +{ +	struct dmar_rmrr_unit *rmrr; +	int i; + +	for_each_rmrr_units(rmrr) { +		for (i = 0; i < rmrr->devices_cnt; i++) { +			/* +			 * Return TRUE if this RMRR contains the device that +			 * is passed in. +			 */ +			if (rmrr->devices[i] == dev) +				return true; +		} +	} +	return false; +} +  static int iommu_should_identity_map(struct pci_dev *pdev, int startup)  { + +	/* +	 * We want to prevent any device associated with an RMRR from +	 * getting placed into the SI Domain. This is done because +	 * problems exist when devices are moved in and out of domains +	 * and their respective RMRR info is lost. We exempt USB devices +	 * from this process due to their usage of RMRRs that are known +	 * to not be needed after BIOS hand-off to OS. +	 */ +	if (device_has_rmrr(pdev) && +	    (pdev->class >> 8) != PCI_CLASS_SERIAL_USB) +		return 0; +  	if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))  		return 1;  | 
