*********************
目录:
1、
从__start_xen开始的vt-d的实现过程
2、虚拟机创建时(dom0)vt-d的初始化过程
3、xen直接设备分配虚拟机的创建流程
*********************
1、从__start_xen开始的vt-d的实现过程
包括检测DMAR信息,硬件的初始化,中断irq, msi初始化,中断重映射,设置root entry等
|-__start_xen
|-iommu_setup()
|-
if ( iommu_enable ){
|-iommu_hardware_setup()
|-intel_vtd_setup() // 若为X86_VENDOR_INTEL 的VT-d
|-查看DMAR ACPI表,确定VT-d功能是否支持
|-iommu_set_interrupt(drhd) // error发生时的Interrupt(MSI)
|-irq = create_irq()
|-desc->handler = &dma_msi_type
|-desc = irq_to_desc(irq)
|- request_irq(irq, iommu_page_fault, 0, "dmar", iommu)
|-dma msi set
|-init_vtd_hw() //Basic VT-d HW init: set VT-d interrupt, clear VT-d faults
|- enable_qinval(iommu) //Enable queue invalidation
|-enable_intremap(iommu, 0) //Enable interrupt remapping
|-iommu_set_root_entry(iommu) // Set root entries for each VT-d engine. After set root entry
|-}
|-printk("I/O virtualisation enabled!\n")
2、虚拟机创建时(dom0)vt-d的初始化过程
获取vt-d的具体操作函数
intel_iommu_ops
,设置dma的page table entry 页表项的地址,设置dom0中需要passthrough的设备,设置IOTLB上下文,设置地址转换ats
|-create_domain()
|-domain_create()
|-arch_domain_create()
|-
iommu_domain_init()
|-if ( !iommu_enabled )
return 0;
|-hd->platform_ops = iommu_get_ops()
|- intel_iommu_ops() ==
intel_iommu_ops
|-hd->platform_ops->init(d) == intel_iommu_domain_init
|-if (domid == 0){ //若domid为0的话,则上一步的init函数的操作函数为
intel_iommu_dom0_init
|-
intel_iommu_dom0_init()
|-iommu_set_dom0_mapping(d) //* Set up 1:1 page table for dom0 */
|-iommu_map_page = intel_iommu_map_page,
|-/* do nothing if dom0 and iommu supports pass thru */
|-
dma_set_pte_addr(GPA,HPA) //设置dma的page table entry 页表项的地址
|-dma_set_pte_prot(IOMMUF_readable | IOMMUF_writable) //设置页表项的属性为read|write
|-setup_dom0_pci_devices(
setup_dom0_device )
|-for(all devices){
|-
domain_context_mapping()
|-domain_context_mapping_one()
|-if ( iommu_passthrough && (domain->domain_id == 0) )
|-context_set_translation_type(*context,
CONTEXT_TT_PASS_THRU)
|-}else{
|-context_set_address_root()
|-context_set_translation_type(*context,
CONTEXT_TT_DEV_IOTLB)
|-}
|-context_set_fault_enable(*context)
|-context_set_present(*context)
|-
intel_iommu_ops
.enable_device = intel_iommu_enable_device
|-ats_device(pdev, drhd) // ATS(Address Translation Services)
|-enable_ats_device()
|} // end for(all devices)
|} //end if(domid =0 )
3、xen直接设备分配虚拟机的创建流程:
根据虚拟机配置文件的pci命令参数,调用libxl中的函数,初始化device pci设备,使用毁掉函数callback调用domcreate_attach_pci增加pci设备,xc_assign_device通过系统调用XEN_DOMCTL_assign_device分配设备
|-xl.c 中的cmd_table[] 的main_create成员
|-main_create
|-
create_domain
|-parse_config_data()
|-xlu_cfg_get_list (config, "
pci", &pcis, 0, 0) //从虚拟机配置文件中读取到pci =['00:03.0']参数的话
|-
libxl_device_pci_init(pcidev) //调用libxl中的函数,初始化device pci设备。libxl最终会掉入qemu中
|-xlu_pci_parse_bdf() //解析上一个过程中pcidev的BDF信息
|-libxl_domain_create_new() //创建新的虚拟机
|-do_domain_create()
|-initiate_domain_create()
|-domcreate_bootloader_done()
|-dcs->dmss.dm.callback = domcreate_devmodel_started()
|-dcs->multidev.callback = domcreate_attach_devs
|-dcs->multidev.callback = domcreate_attach_pci
|-libxl__device_pci_add()
|-do_pci_add()
|-
xc_assign_device() //陷入Libxc中,系统调用
|-domctl.cmd =
XEN_DOMCTL_assign_device
|-do_domctl(xch, &domctl) //跳入iommu.c中执行系统调用