From 8e604097ddc483eb1e6e99564953e4e937fe439a Mon Sep 17 00:00:00 2001 From: Weidong Han Date: Mon, 8 Dec 2008 15:49:06 +0800 Subject: 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 Signed-off-by: Joerg Roedel --- drivers/pci/intel-iommu.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers/pci/intel-iommu.c') diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 3ecfa2304c2..104e99df2ad 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -221,6 +221,8 @@ struct dmar_domain { int agaw; int flags; /* flags to find out type of domain */ + + int iommu_coherency;/* indicate coherency of iommu access */ }; /* PCI domain-device relationship */ @@ -396,6 +398,23 @@ static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain) return g_iommus[iommu_id]; } +/* "Coherency" capability may be different across iommus */ +static void domain_update_iommu_coherency(struct dmar_domain *domain) +{ + int i; + + domain->iommu_coherency = 1; + + i = find_first_bit(&domain->iommu_bmp, g_num_of_iommus); + for (; i < g_num_of_iommus; ) { + if (!ecap_coherent(g_iommus[i]->ecap)) { + domain->iommu_coherency = 0; + break; + } + i = find_next_bit(&domain->iommu_bmp, g_num_of_iommus, i+1); + } +} + /* Gets context entry for a given bus and devfn */ static struct context_entry * device_to_context_entry(struct intel_iommu *iommu, u8 bus, u8 devfn) @@ -1346,6 +1365,11 @@ static int domain_init(struct dmar_domain *domain, int guest_width) domain->agaw = agaw; INIT_LIST_HEAD(&domain->devices); + if (ecap_coherent(iommu->ecap)) + domain->iommu_coherency = 1; + else + domain->iommu_coherency = 0; + /* always allocate the top pgd */ domain->pgd = (struct dma_pte *)alloc_pgtable_page(); if (!domain->pgd) -- cgit v1.2.3