diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-05-06 11:42:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-05-06 11:42:24 -0400 |
commit | 772d4f84c6010f80a932f9e7e47a8acbbc0a527b (patch) | |
tree | ed746aa31d3f4c70ce541a11aab9080deb11b31b /drivers | |
parent | 9c48eb6aabf0d180159c128403c366aab80a57a6 (diff) | |
parent | 40fa84e10134ef5c892b628e02382349b5db3e0c (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.c | 2 | ||||
-rw-r--r-- | drivers/iommu/dma-iommu.c | 54 | ||||
-rw-r--r-- | drivers/iommu/dmar.c | 2 | ||||
-rw-r--r-- | drivers/iommu/intel_irq_remapping.c | 2 | ||||
-rw-r--r-- | drivers/iommu/rockchip-iommu.c | 11 |
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 | ||
84 | static DEFINE_SPINLOCK(amd_iommu_devtable_lock); | 84 | static DEFINE_SPINLOCK(amd_iommu_devtable_lock); |
85 | static DEFINE_SPINLOCK(pd_bitmap_lock); | 85 | static DEFINE_SPINLOCK(pd_bitmap_lock); |
86 | static DEFINE_SPINLOCK(iommu_table_lock); | ||
87 | 86 | ||
88 | /* List of all available dev_data structures */ | 87 | /* List of all available dev_data structures */ |
89 | static LLIST_HEAD(dev_data_list); | 88 | static LLIST_HEAD(dev_data_list); |
@@ -3562,6 +3561,7 @@ EXPORT_SYMBOL(amd_iommu_device_info); | |||
3562 | *****************************************************************************/ | 3561 | *****************************************************************************/ |
3563 | 3562 | ||
3564 | static struct irq_chip amd_ir_chip; | 3563 | static struct irq_chip amd_ir_chip; |
3564 | static DEFINE_SPINLOCK(iommu_table_lock); | ||
3565 | 3565 | ||
3566 | static void set_dte_irq_entry(u16 devid, struct irq_remap_table *table) | 3566 | static 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 | */ |
174 | void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list) | 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 | |||
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(®ion->list, list); | ||
203 | } | ||
204 | } | 180 | } |
205 | EXPORT_SYMBOL(iommu_dma_get_resv_regions); | 181 | EXPORT_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 | ||
208 | static 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 | |||
232 | static int iova_reserve_iommu_regions(struct device *dev, | 225 | static 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); |