diff options
author | Weidong Han <weidong.han@intel.com> | 2008-12-08 02:49:06 -0500 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2009-01-03 08:02:18 -0500 |
commit | 8e604097ddc483eb1e6e99564953e4e937fe439a (patch) | |
tree | bbdae0a23cfa2248db27aa0e85bd82733811b108 /drivers/pci/intel-iommu.c | |
parent | 1b5736839ae13dadc5947940144f95dd0f4a4a8c (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>
Diffstat (limited to 'drivers/pci/intel-iommu.c')
-rw-r--r-- | drivers/pci/intel-iommu.c | 24 |
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 */ | ||
402 | static 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 */ |
400 | static struct context_entry * device_to_context_entry(struct intel_iommu *iommu, | 419 | static 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) |