summaryrefslogtreecommitdiff
path: root/drivers/iommu/intel-iommu.c
diff options
context:
space:
mode:
authorJoerg Roedel <jroedel@suse.de>2015-06-12 10:14:02 +0200
committerJoerg Roedel <jroedel@suse.de>2015-06-16 10:59:34 +0200
commit4158c2eca3c77ed3cccdcaeab153aad4e433369c (patch)
tree9a4b82ece9257f547d8958d1925c128e2d0f266b /drivers/iommu/intel-iommu.c
parent5f0a7f7614a9d99325ac8d618f1cdf7a3014287c (diff)
iommu/vt-d: Detect pre enabled translation
Add code to detect whether translation is already enabled in the IOMMU. Save this state in a flags field added to struct intel_iommu. Tested-by: ZhenHua Li <zhen-hual@hp.com> Tested-by: Baoquan He <bhe@redhat.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/intel-iommu.c')
-rw-r--r--drivers/iommu/intel-iommu.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index bf3e450b5b97..39b90621a1a1 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -443,6 +443,20 @@ static LIST_HEAD(device_domain_list);
static const struct iommu_ops intel_iommu_ops;
+static bool translation_pre_enabled(struct intel_iommu *iommu)
+{
+ return (iommu->flags & VTD_FLAG_TRANS_PRE_ENABLED);
+}
+
+static void init_translation_status(struct intel_iommu *iommu)
+{
+ u32 gsts;
+
+ gsts = readl(iommu->reg + DMAR_GSTS_REG);
+ if (gsts & DMA_GSTS_TES)
+ iommu->flags |= VTD_FLAG_TRANS_PRE_ENABLED;
+}
+
/* Convert generic 'struct iommu_domain to private struct dmar_domain */
static struct dmar_domain *to_dmar_domain(struct iommu_domain *dom)
{
@@ -2809,6 +2823,11 @@ static int __init init_dmars(void)
if (ret)
goto free_iommu;
+ init_translation_status(iommu);
+
+ if (translation_pre_enabled(iommu))
+ pr_info("Translation already enabled - trying to copy translation structures\n");
+
/*
* TBD:
* we could share the same root & context tables