iommu的两大功能,一个是dma 映射,一个是中断的映射。本文简单描述对应的内核参数解析。
1、在iommu 内核参数的解析的 x86架构整体部分
iommu= [x86] off
force
noforce
biomerge
panic
nopanic
merge
nomerge
soft //caq:没有iommu硬件,使用软件来达到iommu的功能,主要是针对bounce buffering
pt [x86]
nopt [x86]
nobypass [PPC/POWERNV] Disable IOMMU bypass, using IOMMU for PCI devices.
对应的代码解析为:
static __init int iommu_setup(char *p)
{
iommu_merge = 1;//caq:默认使能sg合并
if (!p)
return -EINVAL;
while (*p) {
if (!strncmp(p, "off", 3))//caq:不要iommu功能,不管是硬件的iommu还是 swiotlb
no_iommu = 1;
/* gart_parse_options has more force support */
if (!strncmp(p, "force", 5))//caq: 强制使用硬件IOMMU,即使硬件可能有缺陷或者机器内存很少
force_iommu = 1;
if (!strncmp(p, "noforce", 7)) {//caq:默认就是非强制 ,此时 会设置 force_iommu 为0
iommu_merge = 0;
force_iommu = 0;
}
if (!strncmp(p, "biomerge", 8)) {//caq:和 merge 参数一样
iommu_merge = 1;
force_iommu = 1;
}
if (!strncmp(p, "panic", 5))//caq:dma_map_area overflow时 是否触发panic
panic_on_overflow = 1;
if (!strncmp(p, "nopanic", 7))//caq:dma_map_area overflow 时是否关闭panic
panic_on_overflow = 0;
if (!strncmp(p, "merge", 5)) {//caq:会强制iommu,并且要求"scatter-gather"合并
iommu_merge = 1;
force_iommu = 1;
}
if (!strncmp(p, "nomerge", 7))//caq:禁止"scatter-gather"合并,主要用于分散聚集dma
iommu_merge = 0;
if (!strncmp(p, "forcesac", 8))//caq:过期的参数了
pr_warn("forcesac option ignored.\n");
if (!strncmp(p, "allowdac", 8))//caq:同上
pr_warn("allowdac option ignored.\n");
if (!strncmp(p, "nodac", 5))//caq:同上
pr_warn("nodac option ignored.\n");
if (!strncmp(p, "usedac", 6)) {//caq: usedac 一般也不配置,这样disable_dac_quirk 默认为0
disable_dac_quirk = true;//caq:将32位PCI地址用两个时钟周期推入64位地址,这就是DAC的作用。
return 1;
}
#ifdef CONFIG_SWIOTLB
if (!strncmp(p, "soft", 4))//caq:使用 swiotlb ,主要用于bounce buffering,拷贝+sync
swiotlb = 1;
#endif
if (!strncmp(p, "pt", 2))
iommu_pass_through = 1;//caq:设置为pt,则使能 iommu_pass_through
if (!strncmp(p, "nopt", 4))//caq:设置了nopt,则关闭 iommu_pass_through
iommu_pass_through = 0;
gart_parse_options(p);
#ifdef CONFIG_CALGARY_IOMMU
if (!strncmp(p, "calgary", 7))//caq:IBM Calgary 的支持,我们一般用不到
use_calgary = 1;
#endif /* CONFIG_CALGARY_IOMMU */
p += strcspn(p, ",");
if (*p == ',')
++p;
}
return 0;
}
另外还有一个参数
iommu.passthrough= [ARM64] Configure DMA to bypass the IOMMU by default.
Format: { "0" | "1" } 0 - Use IOMMU translation for DMA. 1 - Bypass the IOMMU for DMA.
unset - Use IOMMU translation for DMA.
虽然写的是arm64,但是实际代码的作用区域是:
static int __init iommu_set_def_domain_type(char *str)
{
bool pt;
int ret;
ret = kstrtobool(str, &pt);
if (ret)
return ret;
iommu_def_domain_type = pt ? IOMMU_DOMAIN_IDENTITY : IOMMU_DOMAIN_DMA;//为0则uses IOMMU
return 0;
}
early_param("iommu.passthrough", iommu_set_def_domain_type);//caq:是否设定iommu.default_domain的是否bypass---注意,并不一定指arm64
2、在iommu 内核参数的解析的 intel 硬件部分:
intel_iommu= [DMAR] Intel IOMMU driver (DMAR) option
on
Enable intel iommu driver.
off
Disable intel iommu driver.
igfx_off [Default Off]
By default, gfx is mapped as normal device. If a gfx
device has a dedicated DMAR unit, the DMAR unit is
bypassed by not enabling DMAR with this option. In
this case, gfx device will use physical address for
DMA.
forcedac [x86_64]
With this option iommu will not optimize to look
for io virtual address below 32-bit forcing dual
address cycle on pci bus for cards supporting greater
than 32-bit addressing. The default is to look
for translation below 32-bit and if not available
then look in the higher range.
strict [Default Off]
With this option on every unmap_single operation will
result in a hardware IOTLB flush operation as opposed
to batching them for performance.
sp_off [Default Off]
By default, super page will be supported if Intel IOMMU
has the capability. With this option, super page will
not be supported.
ecs_off [Default Off]
By default, extended context tables will be supported if
the hardware advertises that it has support both for the
extended tables themselves, and also PASID support. With
this option set, extended tables will not be used even
on hardware which claims to support them.
tboot_noforce [Default Off]
Do not force the Intel IOMMU enabled under tboot.
By default, tboot will force Intel IOMMU on, which
could harm performance of some high-throughput
devices like 40GBit network cards, even if identity
mapping is enabled.
Note that using this option lowers the security
provided by tboot because it makes the system
vulnerable to DMA attacks.
对应的内核代码
static int __init intel_iommu_setup(char *str)//caq:cmdline参数设定
{
if (!str)
return -EINVAL;
while (*str) {
if (!strncmp(str, "on", 2)) {//caq:开启 intel_iommu 驱动
dmar_disabled = 0;
pr_info("IOMMU enabled\n");
} else if (!strncmp(str, "off", 3)) {//caq:关闭 inetl_iommu 驱动
dmar_disabled = 1;
pr_info("IOMMU disabled\n");
} else if (!strncmp(str, "igfx_off", 8)) {//caq:开启则意味着:allows the GPU to access the physical memory directly without going through the DMAR
dmar_map_gfx = 0;
pr_info("Disable GFX device mapping\n");
} else if (!strncmp(str, "forcedac", 8)) {//caq:强制PCI设备使用DAC,从而禁止进行地址转换
pr_info("Forcing DAC for PCI devices\n");
dmar_forcedac = 1;
} else if (!strncmp(str, "strict", 6)) {//caq:带strict 参数,禁止批量刷写IOTLB
pr_info("Disable batched IOTLB flush\n");
intel_iommu_strict = 1;
} else if (!strncmp(str, "sp_off", 6)) {//caq:关闭super page支持(默认值为开启),非4k的page叫超级页
pr_info("Disable supported super page\n");
intel_iommu_superpage = 0;
} else if (!strncmp(str, "ecs_off", 7)) {//caq:ecs 就是 extended context
printk(KERN_INFO
"Intel-IOMMU: disable extended context table support\n");
intel_iommu_ecs = 0;
} else if (!strncmp(str, "pasid28", 7)) {//caq: pasid 支持
printk(KERN_INFO
"Intel-IOMMU: enable pre-production PASID support\n");
intel_iommu_pasid28 = 1;
iommu_identity_mapping |= IDENTMAP_GFX;
} else if (!strncmp(str, "tboot_noforce", 13)) {//caq:安全boot
printk(KERN_INFO
"Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n");
intel_iommu_tboot_noforce = 1;
}
str += strcspn(str, ",");
while (*str == ',')
str++;
}
return 0;
}
