Skip to content

Commit

Permalink
Merge tag 'iommu-fixes-v4.17-rc4' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/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()
  • Loading branch information
torvalds committed May 6, 2018
2 parents 9c48eb6 + 40fa84e commit 772d4f8
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 34 deletions.
2 changes: 1 addition & 1 deletion drivers/iommu/amd_iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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)
{
Expand Down
54 changes: 25 additions & 29 deletions drivers/iommu/dma-iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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(&region->list, list);
}
}
EXPORT_SYMBOL(iommu_dma_get_resv_regions);

Expand Down Expand Up @@ -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)
{
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion drivers/iommu/dmar.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion drivers/iommu/intel_irq_remapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
11 changes: 9 additions & 2 deletions drivers/iommu/rockchip-iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 772d4f8

Please sign in to comment.