一个设备关联到一个iommu_group,且和iommu_domain关联。一个domain代表一张映射表。
如果一个设备将驱动绑定到vfio。那么vfio会重新创建一个domain和这个设备关联,不过这个domain的type是IOMMU_DOMAIN_UNMANAGED。使用的依然是同一个组。使用iommu_domain_alloc函数创建。
[ 658.270026] ===arm_smmu_init_domain_context 0 domain ffff00ff8da47758 type 1 dev 0000:0b:10.1 pgtbl_ops 0
[ 658.279573] CPU: 31 PID: 7196 Comm: qemu-kvm Kdump: loaded Tainted: G E 5.10.134.anolis+ #24
[ 658.289264] Hardware name: PHYTIUM LTD Phytium S2500/64/Phytium S2500/64, BIOS V2.2 Feb 9 2021
[ 658.297918] Call trace:
[ 658.300358] dump_backtrace+0x0/0x210
[ 658.304002] show_stack+0x20/0x30
[ 658.307302] dump_stack+0xd8/0x130
[ 658.310689] arm_smmu_attach_dev+0x250/0x998
[ 658.314938] __iommu_attach_device+0x2c/0xd8
[ 658.319185] __iommu_attach_group+0x64/0xa0
[ 658.323346] iommu_attach_group+0x3c/0x60
[ 658.327341] vfio_iommu_attach_group.isra.28+0x44/0x50 [vfio_iommu_type1]
[ 658.334096] vfio_iommu_type1_attach_group+0x204/0x8e0 [vfio_iommu_type1]
[ 658.340853] vfio_fops_unl_ioctl+0x190/0x298 [vfio]
[ 658.345709] __arm64_sys_ioctl+0xb0/0xf0
[ 658.349612] el0_svc_common+0xbc/0x210
[ 658.353341] do_el0_svc+0x30/0xa0
[ 658.356640] el0_svc+0x20/0x30
[ 658.359679] el0_sync_handler+0x90/0xb8
[ 658.363496] el0_sync+0x160/0x180
[ 658.366819] ===arm_smmu_init_domain_context 1 domain ffff00ff8da47758 dev 0000:0b:10.1 pgtbl_ops ffff00ff8da47658
[ 658.377158] ===arm_smmu_init_domain_context 2 domain ffff00ff8da47758 dev 0000:0b:10.1 pgtbl_ops ffff00ff8da47658
前面了解到一个dma_map_ops和设备关联。当驱动使用dma的map接口进行iova和phys地址映射。在透传设备的时候,map的操作实际上上guestOS进行的行为,这种操作应该会触发kvm/qemu进行拦截。qemu/kvm将执行map操作进行iova和vaddr的管理。。。。
默认vfio驱动会创建/dev/vfio/vfio的miscdevice设备:
其它的设备数字形式的代表的iommu_group号,和/sys/kernel/iommu_groups/下的一致,因为是用一个设备透传到虚拟机。
[root@localhost ~]# ls /dev/vfio/ -l
total 0
crw------- 1 root root 244, 0 Feb 9 16:24 1
crw-rw-rw- 1 root root 10, 196 Feb 9 16:24 vfio
虚拟机的map流程:
[ 230.740469] ===__arm_lpae_map iova 10000 paddr 379cd470000 size 65536
[ 230.747060] CPU: 120 PID: 7459 Comm: qemu-kvm Kdump: loaded Not tainted 4.19.0l+ #44
[ 230.754767] Hardware name: PHYTIUM LTD Phytium S2500/64/Phytium S2500/64, BIOS V2.2 Feb 9 2021
[ 230.763423] Call trace:
[ 230.765860] dump_backtrace+0x0/0x1c0
[ 230.769506] show_stack+0x24/0x30
[ 230.772806] dump_stack+0x9c/0xbc
[ 230.776107] __arm_lpae_map+0x94/0x2f0
[ 230.779839] __arm_lpae_map+0x190/0x2f0
[ 230.783657] arm_lpae_map+0xf8/0x128
[ 230.787216] arm_smmu_map+0x90/0xb0
[ 230.790689] iommu_map+0xdc/0x280
[ 230.793991] vfio_iommu_type1_attach_group+0x4d8/0x738 [vfio_iommu_type1]
[ 230.800748] vfio_fops_unl_ioctl+0x16c/0x290 [vfio]
[ 230.805604] do_vfs_ioctl+0xc4/0x838
[ 230.809164] ksys_ioctl+0x84/0xb8
[ 230.812464] __arm64_sys_ioctl+0x28/0x38
[ 230.816368] el0_svc_handler+0xac/0xf8
[ 230.820099] el0_svc+0x8/0xc
static long vfio_iommu_type1_ioctl(void *iommu_data,
unsigned int cmd, unsigned long arg)
{
..............
} else if (cmd == VFIO_IOMMU_MAP_DMA) {
struct vfio_iommu_type1_dma_map map;
uint32_t mask = VFIO_DMA_MAP_FLAG_READ |
VFIO_DMA_MAP_FLAG_WRITE;
minsz = offsetofend(struct vfio_iommu_type1_dma_map, size);
if (copy_from_user(&map, (void __user *)arg, minsz))
return -EFAULT;
printk("===vfio_iommu_type1_ioctl cmd VFIO_IOMMU_MAP_DMA iova %llx vaddr %llx size %llx\n",map.iova,map.vaddr,map.size);
i

最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



