一种虚拟机pci设备透传方法和系统的制作方法_2

文档序号:8942901阅读:来源:国知局
实施例提供的技术方案可以看出,本发明实施例通过宿主机为虚拟机分配预留内存;将虚拟机的待映射内存和宿主机的预留内存按照1:1建立映射关系;虚拟机中安装驱动,申请虚拟机中固定内存中的空闲内存;加载PCI设备驱动,PCI设备根据所述映射关系发起DMA操作,直接访问宿主机内存。解决在没有VT-d/1MMU的CPU主板上无法透传PCI设备到QEMU/KVM虚拟机的问题,使PCI设备直接发起DMA操作,直接访问宿主机内存,这可以大大降低PCI设备透传的成本,并为硬件选型提供更多选择。
【附图说明】
[0063]为了更清楚地说明本发明实施例的技术方案,下面将对实施例描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。
[0064]图1为现有技术虚拟机物理内存GPA到宿主机物理内存HPA转换图;
[0065]图2为现有的基于VT-d/1MMU的PCI设备透传方案图;
[0066]图3为以Windows 7虚拟机为例虚拟机物理内存GPA到宿主机物理内存HPA转换图;
[0067]图4为本发明的PCI设备透传方案图;
[0068]图5为本发明实施例一提供的一种虚拟机PCI设备透传方法的处理流程图;
[0069]图6为本发明实施例二提供的一种虚拟机PCI设备透传系统的模块图。
【具体实施方式】
[0070]为便于对本发明实施例的理解,下面将结合附图以几个具体实施例为例做进一步的解释说明,且各个实施例并不构成对本发明实施例的限定。
[0071]实施例一
[0072]首先在宿主机中需要采用标识标注预留内存,比如在内核的引导参数中加上:memmap = 1536M$512M ;
[0073]如附图3所示,以Windows 7虚拟机为例,这样就可以预留宿主机从512M开始之后的(512+1536)M的内存;这样宿主机就不会去使用这部分内存,预留内存用于与虚拟机建立映射关系。
[0074]该实施例提供了一种虚拟机PCI设备透传方法的处理流程如图5所示,包括如下的处理步骤:
[0075]步骤11、宿主机为虚拟机分配预留内存;
[0076]可以是宿主机在QEMU中通过mmap/dev/mem为虚拟机分配预留内存;
[0077]mmap是将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。_ap必须以PAGE_SIZEO为单位进行映射,而内存也只能以页为单位进行映射。
[0078]具体地,Linux通过设备文件/dev/mem给用户空间提供了直接访问物理内存的途径。用户空间的应用程序可以通过mmap/dev/mem的方式将某一段物理内存映射到自己的虚拟地址空间,这样应用程序就可以直接访问那段物理内存。
[0079]具体步骤如下:
[0080]宿主机使用open函数打开/dev/mem文件,获取文件句柄;
[0081]将包括所述文件句柄的映射信息传给mmap函数,获取预留内存的虚拟地址;
[0082]通过所述虚拟地址访问为虚拟机分配的预留内存。
[0083]具体的,映射信息包括:所述文件句柄,以及需要映射的物理内存段起始地址、长度、访问权限等信息;将映射信息作为参数传给mmap函数,获取预留内存的虚拟地址,应用程序可以用这个预留内存的虚拟地址来对预留内存进行访问。
[0084]此外,还可通过宿主机创建内核模块为虚拟机分配预留内存,具体地:
[0085]宿主机创建内核模块,为所述内核模块建立mmap操作调用内核的remap_pfn_range函数来做内存映射;
[0086]用mknod命令为所述内核模块生成对应的字符设备文件;
[0087]本实施例中采用/dev/_ap_mem作为字符设备文件,但并不局限于此。在本发明中,这个设备文件/dev/_ap_mem可以用来完全替代系统默认的/dev/mem设备文件。
[0088]使用open函数打开/dev/mem文件,获取文件句柄;
[0089]将包括所述文件句柄的映射信息传给mmap函数,获取预留内存的虚拟地址;
[0090]通过所述虚拟地址对预留内存进行访问。
[0091]步骤12、将虚拟机的待映射内存和宿主机的预留内存按照1:1建立映射关系。
[0092]具体地,建立所述映射关系之前,调整虚拟机内存布局,使所述待映射内存在虚拟机中的物理内存GPA和宿主机的物理内存HPA保持一致。
[0093]如前所述,按照步骤11,通过11111^/(^/11161]1将5121到2048M这段物理内存映射到qemu进程的地址空间中,得到一个起始虚拟地址HVA ;
[0094]将这段内存的起始虚拟地址HVA,虚拟机起始物理内存GPA,以及大小等信息传递给内核中KVM的系统调用。
[0095]KVM_SET_USER_MEMORY_REG1N,
[0096]就可以为虚拟机配置这段内存,为了让虚拟机物理内存GPA和宿主机物理内存HPAl:1对应,虚拟机起始物理内存GPA必须等于宿主机起始物理内存HPA,也就是512M。
[0097]步骤13、虚拟机中安装驱动申请虚拟机中固定内存中的空闲内存;
[0098]在PCI设备驱动加载之前加载虚拟机中安装的所述驱动。
[0099]固定内存是指在虚拟机中被虚拟机操作系统占用的内存,在固定内存中,存在空闲内存,以Windows 7虚拟机为例,如附图3所示,假设它的0-2M之间的内存为固定内存,固定内存不能用于建立虚拟机和宿主机的映射关系,只能以QEMU/KVM默认的方式来分配这段内存。虚拟机启动后,固定内存一部分被虚拟机操纵系统占用,还有一部分是空闲内存,这部分空闲内存就可能被透传的PCI设备驱动申请到并用作DMA操作,造成内存访问错误,为了保证透传的PCI设备驱动不会申请到这部分内存,因此需要在虚拟机中安装驱动申请虚拟机中固定内存中的空闲内存。
[0100]具体地:根据所述虚拟机的操作系统创建一个空的驱动,在所述驱动中加载的驱动函数里循环调用用于申请指定地址区间内的物理内存的函数,直至将指定地址区间内的物理内存都申请完,结束循环。在本实施例中,指定地址区间内的物理内存是指固定内存中的空闲内存;但不限于此。
[0101]本实施例以Windows 7为例,但不限于在Windows 7中实现,具体步骤如下:
[0102]创建一个空的Windows驱动;
[0103]在驱动中加载的驱动函数为DriverEntry,在DriverEntry中循环调用函数MmAllocateContiguousMemorySpecifyCache,本实施例中,MmAllocateContiguousMemorySpecifyCache用于申请指定地址区间内的物理内存的函数,在此用来申请虚拟机中固定内存中的空闲内存,直到申请失败为止,表示这个区间内已经没有空闲内存。对Windows 7虚拟机来说,这个区间指的是O到2M。
[0104]步骤14、加载PCI设备驱动,PCI设备根据所述映射关系发起DMA操作,直接访问宿主机内存。具体的PCI设备透传方案图如附图4所示。
[0105]虚拟机的待映射内存和宿主机的预留内存按照1:1建立映射关系之后,PCI设备可以发起DMA操作,此时外设访问内存不再需要经过1MMU转换,而是直接访问,由于GPA和HPA已建立了 1:1的映射关系,保证访问的是正确的地址。
[0106]实施例二
[0107]该实施例提供了一种虚拟机PCI设备透传系统,其具体实现结构如图6所示,具体可以包括如下的模块:
[0108]预留模块21:其用于宿主机为虚拟机分配预留内存;
[0109]映射模块22:其用于将虚拟机的待映射内存和宿主机的预留内存按照1:1建立映射关系;
[0110]驱动模块23:其用于在虚拟机中安装驱动申请虚拟机中固定内存中的空闲内存;
[0111]透传模块24:其用于加载PCI设备驱动,PCI设备根据所述映射关系发起DMA操作,直接访问宿主机内存。
[0112]预留模块21,包括:
[0113]第一预留模块211:其用于使宿主机在QEMU中通过mmap/dev/mem为虚拟机分配所述预留内存;或,
[0114]第二预留模块212:其用于使宿主机创建内核模块为虚拟机分配所述预留内存。
[0115]其中,第一预留模块211,包括:
[0116]第一获取组件2111:其用于使宿主机使用open函数打开/dev/mem文件,获取文件句柄;
[0117]第一传递组件2112:其用于将包括所述文件句柄的映射信息传给—ap函数,获取预留内存的虚拟地址;
[0118]第一分配组件2113:其用于通过所述虚拟地址访问为虚拟机分配的预留内存。
[0119]其中,第二预留模块212,包括:
[0120]创建组件2121:其用于使宿主机创建内核模块,为所述内核模块建立_ap操作调用内核的remap_pfn
当前第2页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1