在kernel mainstream
的intel-iommu.c
代码中:
static int __init init_dmars(void)
{
......
if (translation_pre_enabled(iommu) && !is_kdump_kernel()) {
iommu_disable_translation(iommu);
clear_translation_pre_enabled(iommu);
pr_warn("Translation was enabled for %s but we are not in kdump mode\n",
iommu->name);
}
......
}
translation_pre_enabled
函数如下:
static bool translation_pre_enabled(struct intel_iommu *iommu)
{
return (iommu->flags & VTD_FLAG_TRANS_PRE_ENABLED);
}
而VTD_FLAG_TRANS_PRE_ENABLED
赋值是在init_translation_status
函数中:
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;
}
DMAR_GSTS_REG(Global status register)
里DMA_GSTS_TES(Translation Enable Status)
表明是否开启了DMA Remapping
功能。
所以if (translation_pre_enabled(iommu) && !is_kdump_kernel())
这段代码含义是如果这个iommu
硬件单元已经开启了DMA Remapping
功能,但是当前运行的kernel
不是reboot
的kernel
,则当前iommu
硬件状态是不能被认为是正确的,所以要把DMAR_GSTS_REG(Global status register)
寄存器,和iommu->flags
都要重置(clear_translation_pre_enabled
)。
同理,在intel_irq_remapping.c
中,也有类似代码:
static int intel_setup_irq_remapping(struct intel_iommu *iommu)
{
......
if (ir_pre_enabled(iommu)) {
if (iommu_load_old_irte(iommu))
pr_err("Failed to copy IR table for %s from previous kernel\n",
iommu->name);
else
pr_info("Copied IR table for %s from previous kernel\n",
iommu->name);
}
......
}
static int iommu_load_old_irte(struct intel_iommu *iommu)
{
......
if (!is_kdump_kernel()) {
......
}
......
}
参考资料:
[PATCH 04/17] iommu/vt-d: Load old data structures only in kdump kernel;
Intel ® Virtualization Technology for Directed I/O
。