aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWeidong Han <weidong.han@intel.com>2008-12-08 02:49:06 -0500
committerJoerg Roedel <joerg.roedel@amd.com>2009-01-03 08:02:18 -0500
commit8e604097ddc483eb1e6e99564953e4e937fe439a (patch)
treebbdae0a23cfa2248db27aa0e85bd82733811b108
parent1b5736839ae13dadc5947940144f95dd0f4a4a8c (diff)
iommu coherency
In dmar_domain, more than one iommus may be included in iommu_bmp. Due to "Coherency" capability may be different across iommus, set this variable to indicate iommu access is coherent or not. Only when all related iommus in a dmar_domain are all coherent, iommu access of this domain is coherent. Signed-off-by: Weidong Han <weidong.han@intel.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
-rw-r--r--drivers/pci/intel-iommu.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 3ecfa2304c2c..104e99df2ade 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -221,6 +221,8 @@ struct dmar_domain {
221 int agaw; 221 int agaw;
222 222
223 int flags; /* flags to find out type of domain */ 223 int flags; /* flags to find out type of domain */
224
225 int iommu_coherency;/* indicate coherency of iommu access */
224}; 226};
225 227
226/* PCI domain-device relationship */ 228/* PCI domain-device relationship */
@@ -396,6 +398,23 @@ static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
396 return g_iommus[iommu_id]; 398 return g_iommus[iommu_id];
397} 399}
398 400
401/* "Coherency" capability may be different across iommus */
402static void domain_update_iommu_coherency(struct dmar_domain *domain)
403{
404 int i;
405
406 domain->iommu_coherency = 1;
407
408 i = find_first_bit(&domain->iommu_bmp, g_num_of_iommus);
409 for (; i < g_num_of_iommus; ) {
410 if (!ecap_coherent(g_iommus[i]->ecap)) {
411 domain->iommu_coherency = 0;
412 break;
413 }
414 i = find_next_bit(&domain->iommu_bmp, g_num_of_iommus, i+1);
415 }
416}
417
399/* Gets context entry for a given bus and devfn */ 418/* Gets context entry for a given bus and devfn */
400static struct context_entry * device_to_context_entry(struct intel_iommu *iommu, 419static struct context_entry * device_to_context_entry(struct intel_iommu *iommu,
401 u8 bus, u8 devfn) 420 u8 bus, u8 devfn)
@@ -1346,6 +1365,11 @@ static int domain_init(struct dmar_domain *domain, int guest_width)
1346 domain->agaw = agaw; 1365 domain->agaw = agaw;
1347 INIT_LIST_HEAD(&domain->devices); 1366 INIT_LIST_HEAD(&domain->devices);
1348 1367
1368 if (ecap_coherent(iommu->ecap))
1369 domain->iommu_coherency = 1;
1370 else
1371 domain->iommu_coherency = 0;
1372
1349 /* always allocate the top pgd */ 1373 /* always allocate the top pgd */
1350 domain->pgd = (struct dma_pte *)alloc_pgtable_page(); 1374 domain->pgd = (struct dma_pte *)alloc_pgtable_page();
1351 if (!domain->pgd) 1375 if (!domain->pgd)