diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-05-06 05:42:24 -1000 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-05-06 05:42:24 -1000 | 
| commit | 772d4f84c6010f80a932f9e7e47a8acbbc0a527b (patch) | |
| tree | ed746aa31d3f4c70ce541a11aab9080deb11b31b /drivers | |
| parent | 9c48eb6aabf0d180159c128403c366aab80a57a6 (diff) | |
| parent | 40fa84e10134ef5c892b628e02382349b5db3e0c (diff) | |
| download | linux-772d4f84c6010f80a932f9e7e47a8acbbc0a527b.tar.bz2 | |
Merge tag 'iommu-fixes-v4.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull iommu fixes from Joerg Roedel:
 - fix a compile warning in the AMD IOMMU driver with irq remapping
   disabled
 - fix for VT-d interrupt remapping and invalidation size (caused a
   BUG_ON when trying to invalidate more than 4GB)
 - build fix and a regression fix for broken graphics with old DTS for
   the rockchip iommu driver
 - a revert in the PCI window reservation code which fixes a regression
   with VFIO.
* tag 'iommu-fixes-v4.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
  iommu: rockchip: fix building without CONFIG_OF
  iommu/vt-d: Use WARN_ON_ONCE instead of BUG_ON in qi_flush_dev_iotlb()
  iommu/vt-d: fix shift-out-of-bounds in bug checking
  iommu/dma: Move PCI window region reservation back into dma specific path.
  iommu/rockchip: Make clock handling optional
  iommu/amd: Hide unused iommu_table_lock
  iommu/vt-d: Fix usage of force parameter in intel_ir_reconfigure_irte()
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/iommu/amd_iommu.c | 2 | ||||
| -rw-r--r-- | drivers/iommu/dma-iommu.c | 54 | ||||
| -rw-r--r-- | drivers/iommu/dmar.c | 2 | ||||
| -rw-r--r-- | drivers/iommu/intel_irq_remapping.c | 2 | ||||
| -rw-r--r-- | drivers/iommu/rockchip-iommu.c | 11 | 
5 files changed, 37 insertions, 34 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 2a99f0f14795..8fb8c737fffe 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -83,7 +83,6 @@  static DEFINE_SPINLOCK(amd_iommu_devtable_lock);  static DEFINE_SPINLOCK(pd_bitmap_lock); -static DEFINE_SPINLOCK(iommu_table_lock);  /* List of all available dev_data structures */  static LLIST_HEAD(dev_data_list); @@ -3562,6 +3561,7 @@ EXPORT_SYMBOL(amd_iommu_device_info);   *****************************************************************************/  static struct irq_chip amd_ir_chip; +static DEFINE_SPINLOCK(iommu_table_lock);  static void set_dte_irq_entry(u16 devid, struct irq_remap_table *table)  { diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index f05f3cf90756..ddcbbdb5d658 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -167,40 +167,16 @@ EXPORT_SYMBOL(iommu_put_dma_cookie);   * @list: Reserved region list from iommu_get_resv_regions()   *   * IOMMU drivers can use this to implement their .get_resv_regions callback - * for general non-IOMMU-specific reservations. Currently, this covers host - * bridge windows for PCI devices and GICv3 ITS region reservation on ACPI - * based ARM platforms that may require HW MSI reservation. + * for general non-IOMMU-specific reservations. Currently, this covers GICv3 + * ITS region reservation on ACPI based ARM platforms that may require HW MSI + * reservation.   */  void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list)  { -	struct pci_host_bridge *bridge; -	struct resource_entry *window; - -	if (!is_of_node(dev->iommu_fwspec->iommu_fwnode) && -		iort_iommu_msi_get_resv_regions(dev, list) < 0) -		return; - -	if (!dev_is_pci(dev)) -		return; - -	bridge = pci_find_host_bridge(to_pci_dev(dev)->bus); -	resource_list_for_each_entry(window, &bridge->windows) { -		struct iommu_resv_region *region; -		phys_addr_t start; -		size_t length; - -		if (resource_type(window->res) != IORESOURCE_MEM) -			continue; -		start = window->res->start - window->offset; -		length = window->res->end - window->res->start + 1; -		region = iommu_alloc_resv_region(start, length, 0, -				IOMMU_RESV_RESERVED); -		if (!region) -			return; +	if (!is_of_node(dev->iommu_fwspec->iommu_fwnode)) +		iort_iommu_msi_get_resv_regions(dev, list); -		list_add_tail(®ion->list, list); -	}  }  EXPORT_SYMBOL(iommu_dma_get_resv_regions); @@ -229,6 +205,23 @@ static int cookie_init_hw_msi_region(struct iommu_dma_cookie *cookie,  	return 0;  } +static void iova_reserve_pci_windows(struct pci_dev *dev, +		struct iova_domain *iovad) +{ +	struct pci_host_bridge *bridge = pci_find_host_bridge(dev->bus); +	struct resource_entry *window; +	unsigned long lo, hi; + +	resource_list_for_each_entry(window, &bridge->windows) { +		if (resource_type(window->res) != IORESOURCE_MEM) +			continue; + +		lo = iova_pfn(iovad, window->res->start - window->offset); +		hi = iova_pfn(iovad, window->res->end - window->offset); +		reserve_iova(iovad, lo, hi); +	} +} +  static int iova_reserve_iommu_regions(struct device *dev,  		struct iommu_domain *domain)  { @@ -238,6 +231,9 @@ static int iova_reserve_iommu_regions(struct device *dev,  	LIST_HEAD(resv_regions);  	int ret = 0; +	if (dev_is_pci(dev)) +		iova_reserve_pci_windows(to_pci_dev(dev), iovad); +  	iommu_get_resv_regions(dev, &resv_regions);  	list_for_each_entry(region, &resv_regions, list) {  		unsigned long lo, hi; diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index accf58388bdb..460bed4fc5b1 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -1345,7 +1345,7 @@ void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 qdep,  	struct qi_desc desc;  	if (mask) { -		BUG_ON(addr & ((1 << (VTD_PAGE_SHIFT + mask)) - 1)); +		WARN_ON_ONCE(addr & ((1ULL << (VTD_PAGE_SHIFT + mask)) - 1));  		addr |= (1ULL << (VTD_PAGE_SHIFT + mask - 1)) - 1;  		desc.high = QI_DEV_IOTLB_ADDR(addr) | QI_DEV_IOTLB_SIZE;  	} else diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 66f69af2c219..3062a154a9fb 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c @@ -1136,7 +1136,7 @@ static void intel_ir_reconfigure_irte(struct irq_data *irqd, bool force)  	irte->dest_id = IRTE_DEST(cfg->dest_apicid);  	/* Update the hardware only if the interrupt is in remapped mode. */ -	if (!force || ir_data->irq_2_iommu.mode == IRQ_REMAPPING) +	if (force || ir_data->irq_2_iommu.mode == IRQ_REMAPPING)  		modify_irte(&ir_data->irq_2_iommu, irte);  } diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index 5fc8656c60f9..0468acfa131f 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -1098,7 +1098,7 @@ static int rk_iommu_of_xlate(struct device *dev,  	data->iommu = platform_get_drvdata(iommu_dev);  	dev->archdata.iommu = data; -	of_dev_put(iommu_dev); +	platform_device_put(iommu_dev);  	return 0;  } @@ -1175,8 +1175,15 @@ static int rk_iommu_probe(struct platform_device *pdev)  	for (i = 0; i < iommu->num_clocks; ++i)  		iommu->clocks[i].id = rk_iommu_clocks[i]; +	/* +	 * iommu clocks should be present for all new devices and devicetrees +	 * but there are older devicetrees without clocks out in the wild. +	 * So clocks as optional for the time being. +	 */  	err = devm_clk_bulk_get(iommu->dev, iommu->num_clocks, iommu->clocks); -	if (err) +	if (err == -ENOENT) +		iommu->num_clocks = 0; +	else if (err)  		return err;  	err = clk_bulk_prepare(iommu->num_clocks, iommu->clocks);  |