From 4158c2eca3c77ed3cccdcaeab153aad4e433369c Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 12 Jun 2015 10:14:02 +0200 Subject: [PATCH] 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 Tested-by: Baoquan He Signed-off-by: Joerg Roedel --- drivers/iommu/intel-iommu.c | 19 +++++++++++++++++++ include/linux/intel-iommu.h | 4 ++++ 2 files changed, 23 insertions(+) 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 diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index a240e61a7700..b85b81ad5eba 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -320,6 +320,9 @@ enum { MAX_SR_DMAR_REGS }; +#define VTD_FLAG_TRANS_PRE_ENABLED (1 << 0) +#define VTD_FLAG_IRQ_REMAP_PRE_ENABLED (1 << 1) + struct intel_iommu { void __iomem *reg; /* Pointer to hardware regs, virtual addr */ u64 reg_phys; /* physical address of hw register set */ @@ -351,6 +354,7 @@ struct intel_iommu { #endif struct device *iommu_dev; /* IOMMU-sysfs device */ int node; + u32 flags; /* Software defined flags */ }; static inline void __iommu_flush_cache(