| From a4c34ff1c029e90e7d5f8dd8d29b0a93b31c3cb2 Mon Sep 17 00:00:00 2001 |
| From: Joerg Roedel <jroedel@suse.de> |
| Date: Fri, 17 Jun 2016 11:29:48 +0200 |
| Subject: iommu/vt-d: Enable QI on all IOMMUs before setting root entry |
| |
| From: Joerg Roedel <jroedel@suse.de> |
| |
| commit a4c34ff1c029e90e7d5f8dd8d29b0a93b31c3cb2 upstream. |
| |
| This seems to be required on some X58 chipsets on systems |
| with more than one IOMMU. QI does not work until it is |
| enabled on all IOMMUs in the system. |
| |
| Reported-by: Dheeraj CVR <cvr.dheeraj@gmail.com> |
| Tested-by: Dheeraj CVR <cvr.dheeraj@gmail.com> |
| Fixes: 5f0a7f7614a9 ('iommu/vt-d: Make root entry visible for hardware right after allocation') |
| Signed-off-by: Joerg Roedel <jroedel@suse.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/iommu/intel-iommu.c | 17 ++++++++++++----- |
| 1 file changed, 12 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/iommu/intel-iommu.c |
| +++ b/drivers/iommu/intel-iommu.c |
| @@ -3169,11 +3169,6 @@ static int __init init_dmars(void) |
| } |
| } |
| |
| - iommu_flush_write_buffer(iommu); |
| - iommu_set_root_entry(iommu); |
| - iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL); |
| - iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH); |
| - |
| if (!ecap_pass_through(iommu->ecap)) |
| hw_pass_through = 0; |
| #ifdef CONFIG_INTEL_IOMMU_SVM |
| @@ -3182,6 +3177,18 @@ static int __init init_dmars(void) |
| #endif |
| } |
| |
| + /* |
| + * Now that qi is enabled on all iommus, set the root entry and flush |
| + * caches. This is required on some Intel X58 chipsets, otherwise the |
| + * flush_context function will loop forever and the boot hangs. |
| + */ |
| + for_each_active_iommu(iommu, drhd) { |
| + iommu_flush_write_buffer(iommu); |
| + iommu_set_root_entry(iommu); |
| + iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL); |
| + iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH); |
| + } |
| + |
| if (iommu_pass_through) |
| iommu_identity_mapping |= IDENTMAP_ALL; |
| |