IOMMU Fixes for Linux v4.17-rc4
Fixes come with: * Fix for compile warning in 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 PCI window reservation code which fixes a regression with VFIO. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABAgAGBQJa7s0XAAoJECvwRC2XARrj5bAP/RuP5Y+R67+pT4HfWb2gthJN pHwzZL90EG4DU1b5rdzaElWHXtJglqYHaH4QUnuwh/JwLhrOV2goN3EfzYKNfcHF voEzuM5OCP8OX+j6hLvg+Lroq6PktrnKpKlVpQ6CMK4pPTxv/ig72BdQ3iaAsg4y DUtDCJeG0pGSOuK9HBjRhvQtk77tT26Y0nkyDTev1Zk+1kW0yxeEvWPEXOo+rbVQ ZvDUksAiK7iLRTejm+tR/xC8lSs8Tj2o05HTEhfCMTMcChpKeSOunq4TyVMzWDVv xss9dB+7SNxZtKp6Ek+ORMgBpGlP4kKTgeWVLUVHW/3NkQGMeKzrYX8d7rXHcn1m aPNTB2xNcjTV0x8zEsuBCht2aMW4vnxhx0WwqnXxBVGs9X0hwFNeMAXIuzKdZJjo FuCzYpdBooYKyBbL8j7lxBBVGHKwh7DMVw1LDAgCwq14qTXcGA0hL41uCpjsB1Z+ PJHsso5d+7NqXzqQ/h4Hp4gEgIGluKcXtR7M3toriXUW7b4BatdU62CvFL93Wu4S qYV/ShnTVrvEBMGEoM2QHvqnD0zDIsMhVLK5u386nmQRmfv3yj8gN/f/QxecLW3v r5UOMSjIGLv655g4RaVQtG44hTXz7HHuUJIxFKxU7ExufAGkkZLG3k+seokQdeex 3I3I2xnmRwrdSeWcR5tv =RGxK -----END PGP SIGNATURE----- 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()
This commit is contained in:
commit
772d4f84c6
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 (!is_of_node(dev->iommu_fwspec->iommu_fwnode))
|
||||
iort_iommu_msi_get_resv_regions(dev, list);
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue