Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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()

+37 -34
+1 -1
drivers/iommu/amd_iommu.c
··· 83 83 84 84 static DEFINE_SPINLOCK(amd_iommu_devtable_lock); 85 85 static DEFINE_SPINLOCK(pd_bitmap_lock); 86 - static DEFINE_SPINLOCK(iommu_table_lock); 87 86 88 87 /* List of all available dev_data structures */ 89 88 static LLIST_HEAD(dev_data_list); ··· 3561 3562 *****************************************************************************/ 3562 3563 3563 3564 static struct irq_chip amd_ir_chip; 3565 + static DEFINE_SPINLOCK(iommu_table_lock); 3564 3566 3565 3567 static void set_dte_irq_entry(u16 devid, struct irq_remap_table *table) 3566 3568 {
+25 -29
drivers/iommu/dma-iommu.c
··· 167 167 * @list: Reserved region list from iommu_get_resv_regions() 168 168 * 169 169 * IOMMU drivers can use this to implement their .get_resv_regions callback 170 - * for general non-IOMMU-specific reservations. Currently, this covers host 171 - * bridge windows for PCI devices and GICv3 ITS region reservation on ACPI 172 - * based ARM platforms that may require HW MSI reservation. 170 + * for general non-IOMMU-specific reservations. Currently, this covers GICv3 171 + * ITS region reservation on ACPI based ARM platforms that may require HW MSI 172 + * reservation. 173 173 */ 174 174 void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list) 175 175 { 176 - struct pci_host_bridge *bridge; 177 - struct resource_entry *window; 178 176 179 - if (!is_of_node(dev->iommu_fwspec->iommu_fwnode) && 180 - iort_iommu_msi_get_resv_regions(dev, list) < 0) 181 - return; 177 + if (!is_of_node(dev->iommu_fwspec->iommu_fwnode)) 178 + iort_iommu_msi_get_resv_regions(dev, list); 182 179 183 - if (!dev_is_pci(dev)) 184 - return; 185 - 186 - bridge = pci_find_host_bridge(to_pci_dev(dev)->bus); 187 - resource_list_for_each_entry(window, &bridge->windows) { 188 - struct iommu_resv_region *region; 189 - phys_addr_t start; 190 - size_t length; 191 - 192 - if (resource_type(window->res) != IORESOURCE_MEM) 193 - continue; 194 - 195 - start = window->res->start - window->offset; 196 - length = window->res->end - window->res->start + 1; 197 - region = iommu_alloc_resv_region(start, length, 0, 198 - IOMMU_RESV_RESERVED); 199 - if (!region) 200 - return; 201 - 202 - list_add_tail(&region->list, list); 203 - } 204 180 } 205 181 EXPORT_SYMBOL(iommu_dma_get_resv_regions); 206 182 ··· 205 229 return 0; 206 230 } 207 231 232 + static void iova_reserve_pci_windows(struct pci_dev *dev, 233 + struct iova_domain *iovad) 234 + { 235 + struct pci_host_bridge *bridge = pci_find_host_bridge(dev->bus); 236 + struct resource_entry *window; 237 + unsigned long lo, hi; 238 + 239 + resource_list_for_each_entry(window, &bridge->windows) { 240 + if (resource_type(window->res) != IORESOURCE_MEM) 241 + continue; 242 + 243 + lo = iova_pfn(iovad, window->res->start - window->offset); 244 + hi = iova_pfn(iovad, window->res->end - window->offset); 245 + reserve_iova(iovad, lo, hi); 246 + } 247 + } 248 + 208 249 static int iova_reserve_iommu_regions(struct device *dev, 209 250 struct iommu_domain *domain) 210 251 { ··· 230 237 struct iommu_resv_region *region; 231 238 LIST_HEAD(resv_regions); 232 239 int ret = 0; 240 + 241 + if (dev_is_pci(dev)) 242 + iova_reserve_pci_windows(to_pci_dev(dev), iovad); 233 243 234 244 iommu_get_resv_regions(dev, &resv_regions); 235 245 list_for_each_entry(region, &resv_regions, list) {
+1 -1
drivers/iommu/dmar.c
··· 1345 1345 struct qi_desc desc; 1346 1346 1347 1347 if (mask) { 1348 - BUG_ON(addr & ((1 << (VTD_PAGE_SHIFT + mask)) - 1)); 1348 + WARN_ON_ONCE(addr & ((1ULL << (VTD_PAGE_SHIFT + mask)) - 1)); 1349 1349 addr |= (1ULL << (VTD_PAGE_SHIFT + mask - 1)) - 1; 1350 1350 desc.high = QI_DEV_IOTLB_ADDR(addr) | QI_DEV_IOTLB_SIZE; 1351 1351 } else
+1 -1
drivers/iommu/intel_irq_remapping.c
··· 1136 1136 irte->dest_id = IRTE_DEST(cfg->dest_apicid); 1137 1137 1138 1138 /* Update the hardware only if the interrupt is in remapped mode. */ 1139 - if (!force || ir_data->irq_2_iommu.mode == IRQ_REMAPPING) 1139 + if (force || ir_data->irq_2_iommu.mode == IRQ_REMAPPING) 1140 1140 modify_irte(&ir_data->irq_2_iommu, irte); 1141 1141 } 1142 1142
+9 -2
drivers/iommu/rockchip-iommu.c
··· 1098 1098 data->iommu = platform_get_drvdata(iommu_dev); 1099 1099 dev->archdata.iommu = data; 1100 1100 1101 - of_dev_put(iommu_dev); 1101 + platform_device_put(iommu_dev); 1102 1102 1103 1103 return 0; 1104 1104 } ··· 1175 1175 for (i = 0; i < iommu->num_clocks; ++i) 1176 1176 iommu->clocks[i].id = rk_iommu_clocks[i]; 1177 1177 1178 + /* 1179 + * iommu clocks should be present for all new devices and devicetrees 1180 + * but there are older devicetrees without clocks out in the wild. 1181 + * So clocks as optional for the time being. 1182 + */ 1178 1183 err = devm_clk_bulk_get(iommu->dev, iommu->num_clocks, iommu->clocks); 1179 - if (err) 1184 + if (err == -ENOENT) 1185 + iommu->num_clocks = 0; 1186 + else if (err) 1180 1187 return err; 1181 1188 1182 1189 err = clk_bulk_prepare(iommu->num_clocks, iommu->clocks);