接上文。
(4)
for_each_iommu(iommu, drhd) {
if (iommu->qi)
continue;
dmar_fault(-1, iommu);
iommu_disable_irq_remapping(iommu);
dmar_disable_qi(iommu);
}
上面代码含义是如果硬件单元的queued invalidation
还没有初始化,则清掉之前的fault
,并且disable IRQ remapping
和queued invalidation
。
(5)
for_each_iommu(iommu, drhd) {
if (!ecap_ir_support(iommu->ecap))
continue;
if (eim && !ecap_eim_support(iommu->ecap)) {
printk(KERN_INFO "DRHD %Lx: EIM not supported by DRHD, "
" ecap %Lx\n", drhd->reg_base_addr, iommu->ecap);
goto error;
}
}
上述代码含义是如果硬件支持IRQ remapping
并且系统支持x2APIC
模式,如果硬件不支持x2APIC
模式,就失败。
(6)
for_each_iommu(iommu, drhd) {
int ret = dmar_enable_qi(iommu);
if (ret) {
printk(KERN_ERR "DRHD %Lx: failed to enable queued, "
" invalidation, ecap %Lx, ret %d\n",
drhd->reg_base_addr, iommu->ecap, ret);
goto error;
}
}
for_each_iommu(iommu, drhd) {
if (!ecap_ir_support(iommu->ecap))
continue;
if (intel_setup_irq_remapping(iommu, eim))
goto error;
setup = 1;
}
if (!setup)
goto error;
上述代码分别为每个硬件单元enable queued invalidation
和IRQ remapping
。
(7)
irq_remapping_enabled = 1;
/*
* VT-d has a different layout for IO-APIC entries when
* interrupt remapping is enabled. So it needs a special routine
* to print IO-APIC entries for debugging purposes too.
*/
x86_io_apic_ops.print_entries = intel_ir_io_apic_print_entries;
pr_info("Enabled IRQ remapping in %s mode\n", eim ? "x2apic" : "xapic");
return eim ? IRQ_REMAP_X2APIC_MODE : IRQ_REMAP_XAPIC_MODE;
error:
/*
* handle error condition gracefully here!
*/
if (x2apic_present)
pr_warn("Failed to enable irq remapping. You are vulnerable to irq-injection attacks.\n");
return -1;
如果成功的话,返回IRQ_REMAP_XAPIC_MODE(0)
或IRQ_REMAP_X2APIC_MODE(1)
,否则返回-1
。
参考资料:
"BIOS Considerations" in *Intel ® Virtualization Technology for Directed I/O