一種虛擬機(jī)pci設(shè)備透傳方法和系統(tǒng)的制作方法
【技術(shù)領(lǐng)域】
[0001]本發(fā)明涉及媒體通信技術(shù)領(lǐng)域,尤其涉及一種虛擬機(jī)PCI設(shè)備透傳方法和系統(tǒng)。
【背景技術(shù)】
[0002]隨著QEMU/KVM虛擬化技術(shù)應(yīng)用越來越廣泛,在許多場合,模擬的USB、顯卡、網(wǎng)卡等外設(shè)不管在性能還是功能上都已經(jīng)不能滿足日益增長的需求。比如圖形工作站對顯卡的性能要求很高,而QEMU(Quick Emulator)模擬的顯卡不能做硬件加速,根本無法滿足要求。解決這個(gè)問題常用的一種辦法是把宿主機(jī)上的PCI設(shè)備(比如顯卡)直接分配給某個(gè)虛擬機(jī)使用,這種技術(shù)叫PCI設(shè)備透傳,它很好地解決了虛擬環(huán)境下外設(shè)的性能問題。
[0003]現(xiàn)有PCI (Peripheral Component Interconnect)外設(shè)互聯(lián)設(shè)備透傳方案都是基于英特爾 VT_d(Intel Virtualizat1n Technology for Directed 1/0)或者1MMU (input/output memory management unit)來實(shí)現(xiàn)。支持 VT_d 或 1MMU 的 CPU 和主板成本普遍較高,而且相當(dāng)一部分CPU和主板并不支持這項(xiàng)技術(shù),給硬件選型帶來較大困難。在 QEMU(Quick Emulator)/KVM(Kernel Virtual Machine)虛擬機(jī)中實(shí)現(xiàn) PCI 設(shè)備透傳,需要處理好以下四個(gè)方面的問題:
[0004]1.PCI配置空間映射;
[0005]2.PCI內(nèi)存及1/0資源映射;
[0006]3.PCI IRQ 中斷映射;
[0007]4.DMA (直接內(nèi)存訪問)操作。
[0008]對前兩個(gè)問題,可以直接將宿主機(jī)中該P(yáng)CI設(shè)備對應(yīng)的資源文件用_ap方式直接映射到虛擬機(jī)地址空間中即可。對于第3個(gè)問題,可以在內(nèi)核中使用一個(gè)內(nèi)核線程來截獲中斷,然后將中斷注入到虛擬機(jī)中。已有的各種實(shí)現(xiàn)在這三點(diǎn)上也已經(jīng)比較成熟。
[0009]但是對于PCI透傳設(shè)備的DMA操作是PCI設(shè)備透傳的一個(gè)難點(diǎn)。
[0010]從附圖1可以看到QEMU/KVM中,從虛擬機(jī)物理內(nèi)存GPA到宿主機(jī)物理內(nèi)存HPA需要經(jīng)過兩層轉(zhuǎn)換:一次線性映射和一次MMU映射,才能找到對應(yīng)的宿主機(jī)物理內(nèi)存ΗΡΑ。這造成的結(jié)果是GPA和HPA幾乎不可能是1:1對應(yīng)的。
[0011]虛擬機(jī)vCPU在訪問內(nèi)存時(shí),一樣存在這個(gè)地址轉(zhuǎn)換的問題,它通過擴(kuò)展頁表(EPT)技術(shù)從硬件層面上透明的將GPA轉(zhuǎn)換到ΗΡΑ。
[0012]而PCI透傳設(shè)備的直接內(nèi)存存取DMA (Direct Memory Access)操作沒有EPT的支持。虛擬機(jī)的設(shè)備驅(qū)動申請到的DMA內(nèi)存是虛擬機(jī)的物理內(nèi)存GPA,它通過寫該設(shè)備的特定寄存器將這段內(nèi)存的起始地址和大小告知該設(shè)備,然后該設(shè)備就會用這個(gè)地址GPA直接去訪問宿主機(jī)的物理內(nèi)存,只有GPA和HPA是1:1對應(yīng)的情況下,透傳的PCI設(shè)備才能訪問到正確的地址,否則就會產(chǎn)生錯(cuò)誤?,F(xiàn)有的PCI設(shè)備透傳方案都是基于VT-d/10MMU技術(shù)來解決這個(gè)問題,如附圖2所示。
[0013]VT-d和1MMU是類似的10硬件虛擬化技術(shù),VT_d屬于Intel,1MMU則屬于AMD。這項(xiàng)技術(shù)的作用和EPT類似,都是用來將GPA轉(zhuǎn)換為HPA,但服務(wù)對象是外設(shè),而不是vCPU。
[0014]VT-d/1MMU技術(shù)的原理是在外設(shè)和宿主機(jī)物理內(nèi)存中間插入了一個(gè)1MMU硬件單元,在虛擬化環(huán)境中,透傳的PCI設(shè)備發(fā)起DMA操作時(shí),GPA經(jīng)過1MMU轉(zhuǎn)換后,變成正確的HPA。1MMU的地址轉(zhuǎn)換表由QEMU/KVM在虛擬機(jī)初始化時(shí)建立。
[0015]上述現(xiàn)有技術(shù)中的的缺點(diǎn)為:
[0016]1.虛擬化成本高。支持VT-d或1MMU的CPU或主板普遍成本較高。
[0017]2.硬件選型比較困難。相當(dāng)一部分CPU和主板并不支持VT-d或10MMU。
[0018]3.雖然1MMU硬件地址轉(zhuǎn)換效率很高,但因?yàn)槎嗔艘淮蝺?nèi)存地址轉(zhuǎn)換,對性能不可避免會有一定的影響。
【發(fā)明內(nèi)容】
[0019]本發(fā)明的實(shí)施例提供了一種虛擬機(jī)PCI設(shè)備透傳方法和系統(tǒng),本發(fā)明提供了如下方案:
[0020]宿主機(jī)為虛擬機(jī)分配預(yù)留內(nèi)存;
[0021]將虛擬機(jī)的待映射內(nèi)存和宿主機(jī)的預(yù)留內(nèi)存按照1:1建立映射關(guān)系;
[0022]虛擬機(jī)中安裝驅(qū)動申請?zhí)摂M機(jī)中固定內(nèi)存中的空閑內(nèi)存;
[0023]加載PCI設(shè)備驅(qū)動,PCI設(shè)備根據(jù)所述映射關(guān)系發(fā)起DMA操作,直接訪問宿主機(jī)內(nèi)存。
[0024]根據(jù)本發(fā)明的上述方法,所述宿主機(jī)為虛擬機(jī)分配預(yù)留內(nèi)存包括:
[0025]宿主機(jī)在QEMU中通過_ap/dev/mem為虛擬機(jī)分配所述預(yù)留內(nèi)存;或,
[0026]宿主機(jī)創(chuàng)建內(nèi)核模塊為虛擬機(jī)分配所述預(yù)留內(nèi)存。
[0027]根據(jù)本發(fā)明的上述方法,所述宿主機(jī)在QEMU中通過_ap/dev/mem為虛擬機(jī)分配所述預(yù)留內(nèi)存,包括:
[0028]宿主機(jī)使用open函數(shù)打開/dev/mem文件,獲取文件句柄;
[0029]將包括所述文件句柄的映射信息傳給mmap函數(shù),獲取預(yù)留內(nèi)存的虛擬地址;
[0030]通過所述虛擬地址訪問為虛擬機(jī)分配的預(yù)留內(nèi)存。
[0031]根據(jù)本發(fā)明的上述方法,所述宿主機(jī)創(chuàng)建內(nèi)核模塊為虛擬機(jī)分配所述預(yù)留內(nèi)存,包括:
[0032]宿主機(jī)創(chuàng)建內(nèi)核模塊,為所述內(nèi)核模塊建立_ap操作調(diào)用內(nèi)核的remap_pfn_range函數(shù)來做內(nèi)存映射;
[0033]用mknod命令為所述內(nèi)核模塊生成對應(yīng)的字符設(shè)備文件;
[0034]使用open函數(shù)打開/dev/mem文件,獲取文件句柄;
[0035]將包括所述文件句柄的映射信息傳給mmap函數(shù),獲取預(yù)留內(nèi)存的虛擬地址;
[0036]通過所述虛擬地址訪問為虛擬機(jī)分配的預(yù)留內(nèi)存。
[0037]根據(jù)本發(fā)明的上述方法,所述虛擬機(jī)中安裝驅(qū)動申請?zhí)摂M機(jī)中固定內(nèi)存中的空閑內(nèi)存包括,根據(jù)所述虛擬機(jī)的操作系統(tǒng)創(chuàng)建一個(gè)空的驅(qū)動,在所述驅(qū)動中加載的驅(qū)動函數(shù)里循環(huán)調(diào)用用于申請指定地址區(qū)間內(nèi)的物理內(nèi)存的函數(shù),直至將指定地址區(qū)間內(nèi)的物理內(nèi)存都申請完,結(jié)束循環(huán)。
[0038]根據(jù)本發(fā)明的上述方法,還包括,在PCI設(shè)備驅(qū)動加載之前加載虛擬機(jī)中安裝的所述驅(qū)動。
[0039]根據(jù)本發(fā)明的上述方法,建立所述映射關(guān)系之前,包括:調(diào)整虛擬機(jī)內(nèi)存布局,使所述待映射內(nèi)存在虛擬中的物理內(nèi)存GPA和宿主機(jī)的物理內(nèi)存HPA保持一致。
[0040]根據(jù)本發(fā)明的另一方面,還提供一種虛擬機(jī)PCI設(shè)備透傳系統(tǒng),包括:
[0041]預(yù)留模塊:其用于宿主機(jī)為虛擬機(jī)分配預(yù)留內(nèi)存;
[0042]映射模塊:其用于將虛擬機(jī)的待映射內(nèi)存和宿主機(jī)的預(yù)留內(nèi)存按照1:1建立映射關(guān)系;
[0043]驅(qū)動模塊:其用于在虛擬機(jī)中安裝驅(qū)動申請?zhí)摂M機(jī)中固定內(nèi)存中的空閑內(nèi)存;
[0044]透傳模塊:其用于加載PCI設(shè)備驅(qū)動,PCI設(shè)備根據(jù)所述映射關(guān)系發(fā)起DMA操作,直接訪問宿主機(jī)內(nèi)存。
[0045]根據(jù)本發(fā)明的另一方面,所述預(yù)留模塊,包括:
[0046]第一預(yù)留模塊:其用于使宿主機(jī)在QEMU中通過_ap/dev/mem為虛擬機(jī)分配所述預(yù)留內(nèi)存;或,
[0047]第二預(yù)留模塊:其用于使宿主機(jī)創(chuàng)建內(nèi)核模塊為虛擬機(jī)分配所述預(yù)留內(nèi)存。
[0048]根據(jù)本發(fā)明的另一方面,所述第一預(yù)留模塊,包括:
[0049]第一獲取組件:其用于使宿主機(jī)使用open函數(shù)打開/dev/mem文件,獲取文件句柄;
[0050]第一傳遞組件:其用于將包括所述文件句柄的映射信息傳給_ap函數(shù),獲取預(yù)留內(nèi)存的虛擬地址;
[0051]第一分配組件:其用于通過所述虛擬地址訪問為虛擬機(jī)分配的預(yù)留內(nèi)存。
[0052]根據(jù)本發(fā)明的另一方面,所述第二預(yù)留模塊,包括:
[0053]創(chuàng)建組件:其用于使宿主機(jī)創(chuàng)建內(nèi)核模塊,為所述內(nèi)核模塊建立mmap操作調(diào)用內(nèi)核的remap_pfn_range函數(shù)來做內(nèi)存映射;
[0054]生成組件:其用于用mknod命令為所述內(nèi)核模塊生成對應(yīng)的字符設(shè)備文件;
[0055]第二獲取組件:其用于使用open函數(shù)打開/dev/mem文件,獲取文件句柄;
[0056]第二傳遞組件:其用于將包括所述文件句柄的映射信息傳給_ap函數(shù),獲取預(yù)留內(nèi)存的虛擬地址;
[0057]第二分配組件:其用于通過所述虛擬地址訪問為虛擬機(jī)分配的預(yù)留內(nèi)存。
[0058]根據(jù)本發(fā)明的另一方面,所述驅(qū)動模塊,包括:
[0059]驅(qū)動組件:其用于根據(jù)所述虛擬機(jī)的操作系統(tǒng)創(chuàng)建一個(gè)空的驅(qū)動,在所述驅(qū)動中加載的驅(qū)動函數(shù)里循環(huán)調(diào)用用于申請指定地址區(qū)間內(nèi)的物理內(nèi)存的函數(shù),直至將指定地址區(qū)間內(nèi)的物理內(nèi)存都申請完,結(jié)束循環(huán)。
[0060]根據(jù)本發(fā)明的另一方面,還包括:加載組件:其用于在PCI設(shè)備驅(qū)動加載之前加載虛擬機(jī)中安裝的所述驅(qū)動。
[0061]根據(jù)本發(fā)明的另一方面,還包括:調(diào)整組件:其用于建立所述映射關(guān)系之前,調(diào)整虛擬機(jī)內(nèi)存布局,使所述待映射內(nèi)存在虛擬中的物理內(nèi)存GPA和宿主機(jī)的物理內(nèi)存HPA保持一致。
[0062]由上述本發(fā)明的