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