Commit 2e12bc29 authored by Alex Williamson's avatar Alex Williamson Committed by Joerg Roedel

intel-iommu: Default to non-coherent for domains unattached to iommus

domain_update_iommu_coherency() currently defaults to setting domains
as coherent when the domain is not attached to any iommus.  This
allows for a window in domain_context_mapping_one() where such a
domain can update context entries non-coherently, and only after
update the domain capability to clear iommu_coherency.

This can be seen using KVM device assignment on VT-d systems that
do not support coherency in the ecap register.  When a device is
added to a guest, a domain is created (iommu_coherency = 0), the
device is attached, and ranges are mapped.  If we then hot unplug
the device, the coherency is updated and set to the default (1)
since no iommus are attached to the domain.  A subsequent attach
of a device makes use of the same dmar domain (now marked coherent)
updates context entries with coherency enabled, and only disables
coherency as the last step in the process.

To fix this, switch domain_update_iommu_coherency() to use the
safer, non-coherent default for domains not attached to iommus.
Signed-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
Tested-by: default avatarDonald Dutile <ddutile@redhat.com>
Acked-by: default avatarDonald Dutile <ddutile@redhat.com>
Acked-by: default avatarChris Wright <chrisw@sous-sol.org>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarJoerg Roedel <joerg.roedel@amd.com>
parent 5698bd75
...@@ -589,7 +589,9 @@ static void domain_update_iommu_coherency(struct dmar_domain *domain) ...@@ -589,7 +589,9 @@ static void domain_update_iommu_coherency(struct dmar_domain *domain)
{ {
int i; int i;
domain->iommu_coherency = 1; i = find_first_bit(domain->iommu_bmp, g_num_of_iommus);
domain->iommu_coherency = i < g_num_of_iommus ? 1 : 0;
for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus) { for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus) {
if (!ecap_coherent(g_iommus[i]->ecap)) { if (!ecap_coherent(g_iommus[i]->ecap)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment