【精选】IOMMU/SMMUV3代码分析(4)IO设备与SMMU的关联1_iommu_ops_linux解码者的博客
iort_iommu_configure_id
iort_pci_iommu_init
iort_iommu_xlate //根据SMMU类型的acpi_iort_node 找出fwnode_handle,再找出iommu_ops
arm_smmu_iort_xlate
iommu_fwspec_init //kzalloc 创建iommu_fwspec ,关联iommu_fwspec
fwspec->iommu_fwnode = iommu_fwnode(上面找出的类型fwnode_handle)
fwspec->ops = ops
dev_iommu_fwspec_set // dev->iommu->fwspec = fwspec
iort_add_device_replay
iommu_probe_device
__iommu_probe_device
dev_iommu_get //分配dev->iommu (dev_iommu结构体)
iommu_dev = ops->probe_device(dev) //找到device在硬件上关联的iommu_device(arm_smmu_device成员) ------(1)
dev->iommu->iommu_dev = iommu_dev;
iommu_group_get_for_dev //创建iommu_group
group = ops->device_group(dev);
pci_device_group(dev)/generic_device_group(dev) ----- (2)
iommu_group_add_device(group, dev) //添加device到sysfs gorup目录
dev->iommu_group = group;
iommu_group_get
iommu_alloc_default_domain
__iommu_attach_device
(1):arm-smmu-v3.c
arm_smmu_probe_device
dev_iommu_fwspec_get //获取到device的iommu_fwspec
arm_smmu_get_by_fwnode //根据arm_smmu_drivr驱动找设备。。、以及iommu_fwspec->iommu_fwnode
(2)iommu.c
pci_device_group
iommu_group_alloc //分配内存,并创建/sys/kernel/iommu_groups/
kzalloc
ida_simple_get //分配唯一id
kobject_init_and_add
kobject_create_and_add
struct device {
struct fwnode_handle *fwnode;
struct iommu_group *iommu_group;
struct dev_iommu *iommu;
}
struct dev_iommu {
struct mutex lock;
struct iommu_fault_param *fault_param;
struct iopf_device_param *iopf_param;
struct iommu_fwspec *fwspec;
struct iommu_device *iommu_dev;
void *priv;
};
struct iommu_fwspec {
const struct iommu_ops *ops;
struct fwnode_handle *iommu_fwnode;
u32 flags;
unsigned int num_ids;
u32 ids[];
};
//
struct fwnode_handle {
struct fwnode_handle *secondary;
const struct fwnode_operations *ops;
struct device *dev;
struct list_head suppliers;
struct list_head consumers;
u8 flags;
};
设备树:
pci:
[ 2.228735] of_dma_configure_id+0x154/0x280
[ 2.233001] pci_dma_configure+0x44/0xd0
[ 2.236919] really_probe+0xa0/0x490
[ 2.240488] driver_probe_device+0x58/0xc0
[ 2.244579] __device_attach_driver+0xa8/0x10c
[ 2.249016] bus_for_each_drv+0x78/0xd0
[ 2.252845] __device_attach+0xdc/0x180
[ 2.256674] device_attach+0x14/0x20
[ 2.260244] pci_bus_add_device+0x50/0xb4
[ 2.264247] pci_bus_add_devices+0x3c/0x8c
[ 2.268338] pci_host_probe+0x40/0xc4
[ 2.271995] pci_host_common_probe+0x110/0x190
[ 2.276434] platform_drv_probe+0x54/0xb0
[ 2.280437] really_probe+0xe4/0x490
[ 2.284006] driver_probe_device+0x58/0xc0
platform:
[ 3.305584] dump_stack+0xd0/0x12c
[ 3.308982] of_dma_configure_id+0x154/0x280
[ 3.313249] platform_dma_configure+0x20/0x90
[ 3.317600] really_probe+0xa0/0x490
[ 3.321169] driver_probe_device+0x58/0xc0
[ 3.325259] device_driver_attach+0xc0/0xd0
[ 3.329436] __driver_attach+0x84/0x124
[ 3.333265] bus_for_each_dev+0x70/0xd0
[ 3.337094] driver_attach+0x24/0x30
[ 3.340664] bus_add_driver+0x104/0x1ec
[ 3.344493] driver_register+0x78/0x130
[ 3.348323] __platform_driver_register+0x4c/0x60
[ 3.353023] macb_driver_init+0x1c/0x28
[ 3.356852] do_one_initcall+0x50/0x1b0
of_iommu_configure
of_pci_iommu_init //pci
of_iommu_configure_dev_id
of_iommu_xlate
iommu_fwspec_init
of_iommu_configure_device
of_iommu_configure_dev_id
of_iommu_xlate
iommu_fwspec_init
of_iommu_configure_dev
of_iommu_xlate
iommu_fwspec_init