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>
This commit is contained in:
@@ -443,6 +443,20 @@ static LIST_HEAD(device_domain_list);
|
|||||||
|
|
||||||
static const struct iommu_ops intel_iommu_ops;
|
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 */
|
/* Convert generic 'struct iommu_domain to private struct dmar_domain */
|
||||||
static struct dmar_domain *to_dmar_domain(struct iommu_domain *dom)
|
static struct dmar_domain *to_dmar_domain(struct iommu_domain *dom)
|
||||||
{
|
{
|
||||||
@@ -2809,6 +2823,11 @@ static int __init init_dmars(void)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto free_iommu;
|
goto free_iommu;
|
||||||
|
|
||||||
|
init_translation_status(iommu);
|
||||||
|
|
||||||
|
if (translation_pre_enabled(iommu))
|
||||||
|
pr_info("Translation already enabled - trying to copy translation structures\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TBD:
|
* TBD:
|
||||||
* we could share the same root & context tables
|
* we could share the same root & context tables
|
||||||
|
@@ -320,6 +320,9 @@ enum {
|
|||||||
MAX_SR_DMAR_REGS
|
MAX_SR_DMAR_REGS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define VTD_FLAG_TRANS_PRE_ENABLED (1 << 0)
|
||||||
|
#define VTD_FLAG_IRQ_REMAP_PRE_ENABLED (1 << 1)
|
||||||
|
|
||||||
struct intel_iommu {
|
struct intel_iommu {
|
||||||
void __iomem *reg; /* Pointer to hardware regs, virtual addr */
|
void __iomem *reg; /* Pointer to hardware regs, virtual addr */
|
||||||
u64 reg_phys; /* physical address of hw register set */
|
u64 reg_phys; /* physical address of hw register set */
|
||||||
@@ -351,6 +354,7 @@ struct intel_iommu {
|
|||||||
#endif
|
#endif
|
||||||
struct device *iommu_dev; /* IOMMU-sysfs device */
|
struct device *iommu_dev; /* IOMMU-sysfs device */
|
||||||
int node;
|
int node;
|
||||||
|
u32 flags; /* Software defined flags */
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void __iommu_flush_cache(
|
static inline void __iommu_flush_cache(
|
||||||
|
Reference in New Issue
Block a user