Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 772d4f84 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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()
parents 9c48eb6a 40fa84e1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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)
{
+25 −29
Original line number Diff line number Diff line
@@ -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 (!is_of_node(dev->iommu_fwspec->iommu_fwnode))
		iort_iommu_msi_get_resv_regions(dev, list);

		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;

		list_add_tail(&region->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;
+1 −1
Original line number Diff line number Diff line
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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);
}

+9 −2
Original line number Diff line number Diff line
@@ -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);