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

        前面介绍了SMMU设备的生成和识别,但IO设备是如何与SMMU设备关联的呢?一个SMMU设备下面可能有多个IO设备,但每个IO设备只在一个SMMU设备下。

        根据驱动设备模型,当IO设备与IO驱动匹配时,会触发IO驱动的probe函数,在其实在调用驱动probe()之前,会调用与IOMMU相关的函数。其过程如下:

        整个匹配的probe过程中执行的内容较多,这里仅介绍红色部分,即我们关心的DMA相关的设置和设备驱动的probe()(对于IO设备来説,它为IO设备驱动的probe()函数,注意并不是SMMU设备驱动的probe())。

        其中dev->bus->dma_configure()则是本节的重点,它负责将IO设备与SMMU设备关联起来,可见该操作在IO设备的probe()函数之前完成。

        对于platform device,dma_configure的回调函数为platform_dma_configure();对于PCIE设备,dma_configure的回调函数为pci_dma_configure()。但两者最终都调用都一样。

 暂只介绍ACPI方式的DMA配置acpi_dma_confiugre()。

这里主要作如下三个操作:

  1. 函数acpi_arch_dma_setup()返回设备支持DMA大小,对于ARM64上来説,默认为48bit大小;
  2. 函数acpi_iommu_configure_id()获取设备以及对应的SMMU相关的配置如iommu_ops,并probe设备建立dma_domain;后面重点讲解函数iommu_probe_device();
  3. 函数arch_setup_dma_ops()主要对dma_domain分配并初始化IOVA domain;

        其中函数iommu_probe_device()是关联IO设备和SMMU设备的关键函数,它为IO设备分配iommu_device,同时为IO设备分配iommu_group,将IO设备对应在iommu_device加入到iommu_group中。

        在介绍该函数前简单介绍下重要的结构体iommu_ops和几个概念。

1. 结构体iommu_ops

        结构体iommu_ops定义了底层硬件对应的回调函数,对于SMMU或INTEL IOMMU都会基于硬件定义自己的iommu_ops。结构体iommu_ops各成员函数定义和描述如下所示,这里仅作简单介绍:

成员函数

作用

capable

检查能力

domain_alloc

分配iommu domain

domain_free

释放iommu domain

attach_dev

将设备连接到iommu domain

detach_dev

取消设备到iommu domain的连接

map

映射物理连续的内存区域到iommu domain

map_pages

映射一组物理连续的内存区域到iommu domain

unmap

取消物理连续的内存区域到iommu domain的映射

unmap_pages

取消一组物理连续的内存区域到iommu domain的映射

flush_iotlb_all

同步刷新某个domain的所有硬件TLB

iotlb_sync_map

SMMUV3没有定义

iotlb_sync

刷新某个domain的某个范围的TLB

iova_to_phys

将iova转化为物理地址

probe_device

将设备放入到iommu驱动处理

release_device

将设备从iommu驱动处理中释放

Probe_finalize

在设备添加到iommu group并关联到group domain后的最后一步

Device_group

对某个设备找到或分配iommu group

Enable_nesting

使能2个stage

Set_pgtable_quirks

设置页表相关的workaround

Get_resv_regions

获取一个设备保留的区域

Put_resv_regions

释放一个设备保留的区域

Apply_resv_regions

SMMUV3没有定义

Of_xlate

增加master ID到iommu group转换

Is_attach_deferred

ARM没有使用

dev_has/enable/disable_feat

检查/使能/禁用iommu某些特性

Dev_feat_enabled

判断是否使能特性

Aux_attach/detach_dev

Aux-domain的链接或取消链接到设备

Aux_get_pasid

对给定的aux-domain获取pasid

sva_bind

将进程地址空间绑定到设备

Sva_unbind

取消绑定进程地址空间到设备

Sva_get_pasid

获取共SVA相关的PASID

Page_response

处理页请求回复

Cache_invalidate

无效化转换缓存

Sva_bind_gpasid

将guest pasid与mm绑定

sva_unbind_gpasid

将guest pasid与mm取消绑定

Def_domain_type

设备默认的domain类型(SMMUV3没有定义)

Pgsize_bitmap

所有支持的页大小的bitmap

2. IOMMU相关的结构体关系

        Iommu_device对应一个IO设备(或PCIE概念中的Function);

        Iommu_group为共享相同IO地址空间的设备的集合(可能一个或多个);

        Iommu_domain的范围和iommu_group一样,但它定义的是group范围内对应的操作的集合;

 

 

 

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用SMMU的例子: ``` #include <linux/iommu.h> static struct iommu_domain *smmu_domain; static int smmu_probe(struct platform_device *pdev) { /* 初始化SMMU */ smmu_domain = iommu_domain_alloc(&platform_bus_type); if (!smmu_domain) { dev_err(&pdev->dev, "Failed to allocate SMMU domain\n"); return -ENOMEM; } /* 添加设备SMMU域中 */ if (iommu_attach_device(smmu_domain, &pdev->dev)) { dev_err(&pdev->dev, "Failed to attach device to SMMU domain\n"); iommu_domain_free(smmu_domain); return -ENODEV; } return 0; } static int smmu_remove(struct platform_device *pdev) { /* 从SMMU域中移除设备 */ iommu_detach_device(smmu_domain, &pdev->dev); /* 释放SMMU域 */ iommu_domain_free(smmu_domain); return 0; } static const struct of_device_id smmu_of_match[] = { { .compatible = "arm,mmu-500" }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, smmu_of_match); static struct platform_driver smmu_driver = { .probe = smmu_probe, .remove = smmu_remove, .driver = { .name = "smmu", .of_match_table = smmu_of_match, }, }; module_platform_driver(smmu_driver); ``` 这个代码片段是一个SMMU驱动程序的框架,它通过调用`iommu_domain_alloc()`函数分配一个SMMU域,然后通过调用`iommu_attach_device()`函数将设备添加到SMMU域中。当设备被移除时,它会调用`iommu_detach_device()`函数将设备SMMU域中移除,并释放SMMU域。 在实际的驱动程序中,还需要为SMMU设备提供具体的操作函数,如`iommu_ops`结构体中的`map()`、`unmap()`、`flush_iotlb_all()`等。这些函数将被SMMU核心调用以执行特定的操作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值