diff options
author | Takao Indoh <indou.takao@jp.fujitsu.com> | 2013-04-23 17:35:03 +0900 |
---|---|---|
committer | Joerg Roedel <joro@8bytes.org> | 2013-04-23 14:47:08 +0200 |
commit | 3a93c841c2b3b14824f7728dd74bd00a1cedb806 (patch) | |
tree | 7b4a66f8caceac55b0832b635d537f7a04126eae /drivers/iommu/dmar.c | |
parent | 35d3d814cbd46a85bed97cd74ba97fbbb51e0ccd (diff) | |
download | linux-3a93c841c2b3b14824f7728dd74bd00a1cedb806.tar.gz linux-3a93c841c2b3b14824f7728dd74bd00a1cedb806.tar.bz2 linux-3a93c841c2b3b14824f7728dd74bd00a1cedb806.zip |
iommu/vt-d: Disable translation if already enabled
This patch disables translation(dma-remapping) before its initialization
if it is already enabled.
This is needed for kexec/kdump boot. If dma-remapping is enabled in the
first kernel, it need to be disabled before initializing its page table
during second kernel boot. Wei Hu also reported that this is needed
when second kernel boots with intel_iommu=off.
Basically iommu->gcmd is used to know whether translation is enabled or
disabled, but it is always zero at boot time even when translation is
enabled since iommu->gcmd is initialized without considering such a
case. Therefor this patch synchronizes iommu->gcmd value with global
command register when iommu structure is allocated.
Signed-off-by: Takao Indoh <indou.takao@jp.fujitsu.com>
Signed-off-by: Joerg Roedel <joro@8bytes.org>
Diffstat (limited to 'drivers/iommu/dmar.c')
-rw-r--r-- | drivers/iommu/dmar.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index 9f8aa07360ba..f7890edb22f5 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -645,7 +645,7 @@ out: int alloc_iommu(struct dmar_drhd_unit *drhd) { struct intel_iommu *iommu; - u32 ver; + u32 ver, sts; static int iommu_allocated = 0; int agaw = 0; int msagaw = 0; @@ -695,6 +695,15 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) (unsigned long long)iommu->cap, (unsigned long long)iommu->ecap); + /* Reflect status in gcmd */ + sts = readl(iommu->reg + DMAR_GSTS_REG); + if (sts & DMA_GSTS_IRES) + iommu->gcmd |= DMA_GCMD_IRE; + if (sts & DMA_GSTS_TES) + iommu->gcmd |= DMA_GCMD_TE; + if (sts & DMA_GSTS_QIES) + iommu->gcmd |= DMA_GCMD_QIE; + raw_spin_lock_init(&iommu->register_lock); drhd->iommu = iommu; |