IOMMU/SMMUV3代码分析(5)IO设备与SMMU的关联2

        函数Iommu_probe_device()是通过如下图所示建立起IO设备与SMMU的关联:

        其中红色部分会调用SMMUV3驱动中定义的iommu_ops,后面在被调用时再对涉及的回调作介绍。这里分成以下几个部分进行讲解:

1. 为IO设备分配iommu_device

        在上述函数中,通过ops->probe_device()为IO设备分配对应SMMU的iommu_device。对于SMMUV3驱动,ops->probe_device = arm_smmu_probe_device。

         在SMMUV3驱动中先简单介绍涉及的几个结构体:

(1)结构体arm_smmu_device对应于SMMU设备;

(2)结构体arm_smmu_master对应于IO设备;

(3)结构体arm_smmu_stream对应于IO设备中的FUNCTION(若仅一个FUNCTION,也对应IO设备);

        函数定义如下:

        函数执行操作如下:

(1)根据IO设备找到所对应的SMMU设备(结构体arm_smmu_device);

(2)根据IO设备分配所对应在结构体arm_smmu_master;

(3)根据IORT表中定义的IO设备的stream情况分配arm_smmu_stream,若支持二级STE,对STE的第二级STE进行初始化(前面SMMU设备初始化已介绍),并将arm_smmu_stream插入到arm_smmu_device中;

(4)使能PASID;

2. 分配iommu_group并添加IO设备

        函数iommu_group_get_for_dev()首先查找设备是否存在对应的iommu_group,第一次时设备不存在对应的iommu_group,调用ops->device_group()分配或查找iommu_group;调用函数iommu_group_add_device()将IO设备添加到iommu_group。

2.1 分配iommu_group

(1)判断当前设备是否为PCI设备,若为PCI设备,PCIE设备存在alias,尝试使用alias对应的iommu_group;若PCIE设备到root bus之间存在没有使能ACS特性的设备,那么此部分为同一个group,使用对应的group(后续再讲解ACS特性);若PCIE设备对应的function存在alias,尝试使用alias对应的iommu_group;最后调用iommu_group_alloc()分配iommu_group,此函数生成iommu_group,且生成SYSFS属性reserved_regions和type。

(2)若为其他设备如platform设备,同样调用iommu_group_alloc()。

2.2 将IO设备添加到iommu_group

    通过函数iommu_group_add_device()将设备添加到iommu_group。这里通过函数sysfs_create_link()建立起IO设备的device与iommu_group的device相互Link,即从IO设备的device目录可以到达iommu_group对应在device目录,也可从iommu_group的device目录到达IO设备的目录。

        其中对于group->domain且!iommu_is_attach_deferred()情况,将设备与group->domain关联,在第一次时group->domain为空,这里暂且不分析。

3. 为IO设备分配iommu_domain

        对于iommu_group,存在两个iommu_domain: iommu_group->domain(作用?)和iommu_group->default_domain。函数iommu_alloc_default_domain()为iommu_group分配default_domain。

(1)设置DMA类型。若命令行中定义DMA类型,使用命令行中DMA类型;否则使用默认类型;IOMMU_DOMAIN_DMA表示进行DMA转换; IOMMU_DOMAIN_IDENTIFY表示PASSTHROUGH,不经过SMMU;

(2)分配iommu_group->default_domain,这是调用SMMUV3回调函数实现的;

(3)填充iommu_domain对应的成员域;

4. 将IO设备连接到iommu_domain

        通过函数__iommu_attach_device()将IO设备连接到iommu_domain,最后调用SMMUV3驱动回调函数arm_smmu_attach_dev(),它的执行流程如下:

 (1)调用arm_smmu_detach_dev(),作attach_dev相反的操作;

(2)调用arm_smmu_domain_finalise()作与页表相关的设置,后面单独分析;

(3)调用arm_smmu_install_ste_for_dev()设置STE,后面单独介绍;

5. 建立直接映射

        所谓直接映射为IOVA=PA。在某些场景如驱动希望保留部分IOVA区域,或虚拟机中MSI的方案等,都会使用直接映射。调用如下:

(1)获取设备所对应的保留区域;

(2)对每个保留区域,使用iommu_map()建立起IOVA=PA的映射,后面对iommu_map()等 map/unmap API操作讲解;

(3)刷新domain中所有TLB项;

6. 小结

        函数iommu_probe_device()实现IO设备与对应SMMU的关联。在此过程中为IO设备和SMMU设备分配IOMMU框架层和SMMUV3驱动对应的结构体。

IOMMU框架的结构体

SMMUV3驱动对应的结构

含义

Iommu_device

arm_smmu_device

SMMU设备

group_device

arm_smmu_master

IO设备

Iommu_group

arm_smmu_group

IO设备所对应的group

Iommu_domain

arm_smmu_domain

IO设备所对应的domain

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值