从device这个结构体中可以得到struct iommu_group *group;
例如:
struct iommu_group *iommu_group_get(struct device *dev)
{
struct iommu_group *group = dev->iommu_group;
if (group)
kobject_get(group->devices_kobj);
return group;
}
group = iommu_group_get(dev);
而iommu_group 有包含iommu_domain
例如:domain = group->domain;
总结一下:dev->iommu_group->domain.可见domain 代表一个具体的设备使用iommu的详细spec。
有了domian只有就可以通过iommu_dma_init_domain 来设定这个dev使用smmu详细的spec
int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
u64 size, struct device *dev)
{
struct iova_domain *iovad = cookie_iovad(domain);
unsigned long order, base_pfn, end_pfn;
if (!iovad)
return -ENODEV;
/* Use the smallest supported page size for IOVA granularity */
order = __ffs(domain->pgsize_bitmap);
base_pfn = max_t(unsigned long, 1, base >> order);
end_pfn = (base + size - 1) >> order;
}
例如我们会根据domain->pgsize_bitmap 来决定order等。所以说domain 代表这个dev使用iommu详细的spec.
而目前系统中的iommu_group 主要分成两个group,一个是pcie。一个是generic ,这个从下面这个函数中可以看出
static struct iommu_group *arm_smmu_device_group(struct device *dev)
{
struct iommu_group *group;
/*
* We don't support devices sharing stream IDs other than PCI RID
* aliases, since the necessary ID-to-device lookup becomes rather
* impractical given a potential sparse 32-bit stream ID space.
*/
if (dev_is_pci(dev))
group = pci_device_group(dev);
else
group = generic_device_group(dev);
return group;
}
例如:
struct iommu_group *iommu_group_get(struct device *dev)
{
struct iommu_group *group = dev->iommu_group;
if (group)
kobject_get(group->devices_kobj);
return group;
}
group = iommu_group_get(dev);
而iommu_group 有包含iommu_domain
例如:domain = group->domain;
总结一下:dev->iommu_group->domain.可见domain 代表一个具体的设备使用iommu的详细spec。
有了domian只有就可以通过iommu_dma_init_domain 来设定这个dev使用smmu详细的spec
int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
u64 size, struct device *dev)
{
struct iova_domain *iovad = cookie_iovad(domain);
unsigned long order, base_pfn, end_pfn;
if (!iovad)
return -ENODEV;
/* Use the smallest supported page size for IOVA granularity */
order = __ffs(domain->pgsize_bitmap);
base_pfn = max_t(unsigned long, 1, base >> order);
end_pfn = (base + size - 1) >> order;
}
例如我们会根据domain->pgsize_bitmap 来决定order等。所以说domain 代表这个dev使用iommu详细的spec.
而目前系统中的iommu_group 主要分成两个group,一个是pcie。一个是generic ,这个从下面这个函数中可以看出
static struct iommu_group *arm_smmu_device_group(struct device *dev)
{
struct iommu_group *group;
/*
* We don't support devices sharing stream IDs other than PCI RID
* aliases, since the necessary ID-to-device lookup becomes rather
* impractical given a potential sparse 32-bit stream ID space.
*/
if (dev_is_pci(dev))
group = pci_device_group(dev);
else
group = generic_device_group(dev);
return group;
}