aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-05-06 11:42:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-05-06 11:42:24 -0400
commit772d4f84c6010f80a932f9e7e47a8acbbc0a527b (patch)
treeed746aa31d3f4c70ce541a11aab9080deb11b31b /drivers
parent9c48eb6aabf0d180159c128403c366aab80a57a6 (diff)
parent40fa84e10134ef5c892b628e02382349b5db3e0c (diff)
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.c2
-rw-r--r--drivers/iommu/dma-iommu.c54
-rw-r--r--drivers/iommu/dmar.c2
-rw-r--r--drivers/iommu/intel_irq_remapping.c2
-rw-r--r--drivers/iommu/rockchip-iommu.c11
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 @@
83 83
84static DEFINE_SPINLOCK(amd_iommu_devtable_lock); 84static DEFINE_SPINLOCK(amd_iommu_devtable_lock);
85static DEFINE_SPINLOCK(pd_bitmap_lock); 85static DEFINE_SPINLOCK(pd_bitmap_lock);
86static DEFINE_SPINLOCK(iommu_table_lock);
87 86
88/* List of all available dev_data structures */ 87/* List of all available dev_data structures */
89static LLIST_HEAD(dev_data_list); 88static LLIST_HEAD(dev_data_list);
@@ -3562,6 +3561,7 @@ EXPORT_SYMBOL(amd_iommu_device_info);
3562 *****************************************************************************/ 3561 *****************************************************************************/
3563 3562
3564static struct irq_chip amd_ir_chip; 3563static struct irq_chip amd_ir_chip;
3564static DEFINE_SPINLOCK(iommu_table_lock);
3565 3565
3566static void set_dte_irq_entry(u16 devid, struct irq_remap_table *table) 3566static void set_dte_irq_entry(u16 devid, struct irq_remap_table *table)
3567{ 3567{
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);
167 * @list: Reserved region list from iommu_get_resv_regions() 167 * @list: Reserved region list from iommu_get_resv_regions()
168 * 168 *
169 * IOMMU drivers can use this to implement their .get_resv_regions callback 169 * IOMMU drivers can use this to implement their .get_resv_regions callback
170 * for general non-IOMMU-specific reservations. Currently, this covers host 170 * for general non-IOMMU-specific reservations. Currently, this covers GICv3
171 * bridge windows for PCI devices and GICv3 ITS region reservation on ACPI 171 * ITS region reservation on ACPI based ARM platforms that may require HW MSI
172 * based ARM platforms that may require HW MSI reservation. 172 * reservation.
173 */ 173 */
174void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list) 174void 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
179 if (!is_of_node(dev->iommu_fwspec->iommu_fwnode) &&
180 iort_iommu_msi_get_resv_regions(dev, list) < 0)
181 return;
182
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 176
195 start = window->res->start - window->offset; 177 if (!is_of_node(dev->iommu_fwspec->iommu_fwnode))
196 length = window->res->end - window->res->start + 1; 178 iort_iommu_msi_get_resv_regions(dev, list);
197 region = iommu_alloc_resv_region(start, length, 0,
198 IOMMU_RESV_RESERVED);
199 if (!region)
200 return;
201 179
202 list_add_tail(&region->list, list);
203 }
204} 180}
205EXPORT_SYMBOL(iommu_dma_get_resv_regions); 181EXPORT_SYMBOL(iommu_dma_get_resv_regions);
206 182
@@ -229,6 +205,23 @@ static int cookie_init_hw_msi_region(struct iommu_dma_cookie *cookie,
229 return 0; 205 return 0;
230} 206}
231 207
208static void iova_reserve_pci_windows(struct pci_dev *dev,
209 struct iova_domain *iovad)
210{
211 struct pci_host_bridge *bridge = pci_find_host_bridge(dev->bus);
212 struct resource_entry *window;
213 unsigned long lo, hi;
214
215 resource_list_for_each_entry(window, &bridge->windows) {
216 if (resource_type(window->res) != IORESOURCE_MEM)
217 continue;
218
219 lo = iova_pfn(iovad, window->res->start - window->offset);
220 hi = iova_pfn(iovad, window->res->end - window->offset);
221 reserve_iova(iovad, lo, hi);
222 }
223}
224
232static int iova_reserve_iommu_regions(struct device *dev, 225static int iova_reserve_iommu_regions(struct device *dev,
233 struct iommu_domain *domain) 226 struct iommu_domain *domain)
234{ 227{
@@ -238,6 +231,9 @@ static int iova_reserve_iommu_regions(struct device *dev,
238 LIST_HEAD(resv_regions); 231 LIST_HEAD(resv_regions);
239 int ret = 0; 232 int ret = 0;
240 233
234 if (dev_is_pci(dev))
235 iova_reserve_pci_windows(to_pci_dev(dev), iovad);
236
241 iommu_get_resv_regions(dev, &resv_regions); 237 iommu_get_resv_regions(dev, &resv_regions);
242 list_for_each_entry(region, &resv_regions, list) { 238 list_for_each_entry(region, &resv_regions, list) {
243 unsigned long lo, hi; 239 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,
1345 struct qi_desc desc; 1345 struct qi_desc desc;
1346 1346
1347 if (mask) { 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 addr |= (1ULL << (VTD_PAGE_SHIFT + mask - 1)) - 1; 1349 addr |= (1ULL << (VTD_PAGE_SHIFT + mask - 1)) - 1;
1350 desc.high = QI_DEV_IOTLB_ADDR(addr) | QI_DEV_IOTLB_SIZE; 1350 desc.high = QI_DEV_IOTLB_ADDR(addr) | QI_DEV_IOTLB_SIZE;
1351 } else 1351 } 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)
1136 irte->dest_id = IRTE_DEST(cfg->dest_apicid); 1136 irte->dest_id = IRTE_DEST(cfg->dest_apicid);
1137 1137
1138 /* Update the hardware only if the interrupt is in remapped mode. */ 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 modify_irte(&ir_data->irq_2_iommu, irte); 1140 modify_irte(&ir_data->irq_2_iommu, irte);
1141} 1141}
1142 1142
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,
1098 data->iommu = platform_get_drvdata(iommu_dev); 1098 data->iommu = platform_get_drvdata(iommu_dev);
1099 dev->archdata.iommu = data; 1099 dev->archdata.iommu = data;
1100 1100
1101 of_dev_put(iommu_dev); 1101 platform_device_put(iommu_dev);
1102 1102
1103 return 0; 1103 return 0;
1104} 1104}
@@ -1175,8 +1175,15 @@ static int rk_iommu_probe(struct platform_device *pdev)
1175 for (i = 0; i < iommu->num_clocks; ++i) 1175 for (i = 0; i < iommu->num_clocks; ++i)
1176 iommu->clocks[i].id = rk_iommu_clocks[i]; 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 err = devm_clk_bulk_get(iommu->dev, iommu->num_clocks, iommu->clocks); 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 return err; 1187 return err;
1181 1188
1182 err = clk_bulk_prepare(iommu->num_clocks, iommu->clocks); 1189 err = clk_bulk_prepare(iommu->num_clocks, iommu->clocks);