先來看下什麼是徹底虛擬化和半虛擬化. 前端
徹底虛擬化:來賓操做系統運行在位於物理機器上的hypervisor之上.來賓操做系統並不知道它已被虛擬化,而且不須要任何更改就能夠工做. 後端
半虛擬化:來賓操做系統不只知道它運行在hypervisor之上,還包括讓來賓操做系統更高效地過分到hypervisor的代碼 網絡
在徹底虛擬化模式中,hypervisor必須模擬設備硬件,它是在會話的最低級別進行模擬的(例如:網絡驅動程序,磁盤,顯卡等等).儘管在該抽象中模擬很乾淨,但它同時也是最低效,最複雜的.在半虛擬化中,來賓操做系統和hypervisor可以共同合做,讓模擬更加高效.缺點是操做系統知道它被虛擬化,而且須要修改才能工做. 性能
以上是徹底虛擬化和半虛擬化環境下的設備模擬 spa
左圖在傳統的徹底虛擬化環境中,hypervisor必須捕捉這些請求,而後模擬物理硬件的行爲。儘管這也作提供很大的靈活性(即運行未更改的操做系統),但它的效率比較低. 操作系統
右圖,半虛擬化,來賓操做系統知道它運行在hypervisor之上,幷包含了充當當前的驅動程序.hypervisor爲特定的設備模擬實現後端驅動程序.經過在這些前端和後端驅動程序中的virtio,爲開發模擬設備提供標準化接口,從而增長代碼的跨平臺重用率並提升效率. 調試
咱們先來看下QUEM模擬I/O設備的基本原理和優缺點: orm
使用QEMU模擬I/O的狀況下,當客戶機中的設備驅動程序(device driver)發起I/O操做請求之時,KVM模塊中的I/O操做捕獲代碼會攔截此次I/O請求,而後通過處理後將本次I/O請求的信息存放到I/O共享頁,並通知用戶控件的QEMU程序。QEMU模擬程序得到I/O操做的具體信息以後,交由硬件模擬代碼來模擬出本次的I/O操做,完成以後,將結果放回到I/O共享頁,並通知KVM模塊中的I/O操做捕獲代碼。最後,由KVM模塊中的捕獲代碼讀取I/O共享頁中的操做結果,並把結果返回到客戶機中。固然,這個操做過程當中客戶機做爲一個QEMU進程在等待I/O時也可能被阻塞。另外,當客戶機經過DMA(Direct Memory Access)訪問大塊I/O之時,QEMU模擬程序將不會把操做結果放到I/O共享頁中,而是經過內存映射的方式將結果直接寫到客戶機的內存中去,而後經過KVM模塊告訴客戶機DMA操做已經完成。 視頻
QEMU模擬I/O設備的方式,其優勢是能夠經過軟件模擬出各類各樣的硬件設備,包括一些不經常使用的或者很老很經典的設備(如4.5節中提到RTL8139的網卡),並且它不用修改客戶機操做系統,就能夠實現模擬設備在客戶機中正常工做。在KVM客戶機中使用這種方式,對於解決手上沒有足夠設備的軟件開發及調試有很是大的好處。而它的缺點是,每次I/O操做的路徑比較長,有較多的VMEntry、VMExit發生,須要屢次上下文切換(context switch),也須要屢次數據複製,因此它的性能較差。 接口
其中前端驅動(frondend,如virtio-blk、virtio-net等)是在客戶機中存在的驅動程序模塊,然後端處理程序(backend)是在QEMU中實現的。在這先後端驅動之間,還定義了兩層來支持客戶機與QEMU之間的通訊。其中,「virtio」這一層是虛擬隊列接口,它在概念上將前端驅動程序附加到後端處理程序。一個前端驅動程序可使用0個或多個隊列,具體數量取決於需求。例如,virtio-net網絡驅動程序使用兩個虛擬隊列(一個用於接收,另外一個用於發送),而virtio-blk塊驅動程序僅使用一個虛擬隊列。虛擬隊列實際上被實現爲跨越客戶機操做系統和hypervisor的銜接點,但它能夠經過任意方式實現,前提是客戶機操做系統和virtio後端程序都遵循必定的標準,以相互匹配的方式實現它。而virtio-ring實現了環形緩衝區(ring buffer),用於保存前端驅動和後端處理程序執行的信息,而且它能夠一次性保存前端驅動的屢次I/O請求,而且交由後端去動去批量處理,最後實際調用宿主機中設備驅動實現物理上的I/O操做,這樣作就能夠根據約定實現批量處理而不是客戶機中每次I/O請求都須要處理一次,從而提升客戶機與hypervisor信息交換的效率。
Virtio半虛擬化驅動的方式,能夠得到很好的I/O性能,其性能幾乎能夠達到和native(即:非虛擬化環境中的原生系統)差很少的I/O性能。因此,在使用KVM之時,若是宿主機內核和客戶機都支持virtio的狀況下,通常推薦使用virtio達到更好的性能。固然,virtio的也是有缺點的,它必需要客戶機安裝特定的Virtio驅動使其知道是運行在虛擬化環境中,且按照Virtio的規定格式進行數據傳輸,不過客戶機中可能有一些老的Linux系統不支持virtio和主流的Windows系統須要安裝特定的驅動才支持Virtio。不過,較新的一些Linux發行版(如RHEL 6.三、Fedora 17等)默認都將virtio相關驅動編譯爲模塊,可直接做爲客戶機使用virtio,並且對於主流Windows系統都有對應的virtio驅動程序可供下載使用。
virtio是對半虛擬化hypervisor中的一組通用模擬設備的抽象.該設置還容許hypervisor導出一組通用的模擬設備,並經過一個通用的應用程序接口(API)讓它們變得可用.有了半虛擬化hypervisor以後,來賓操做系統可以實現一組通用的接口,在一組後端驅動程序以後採用特定的設備模擬.後端驅動程序不須要是通用的,由於它們只實現前端所需的行爲.
注意,在現實中(儘管不須要),設備模擬發生在使用 QEMU 的空間,所以後端驅動程序與 hypervisor 的用戶空間交互,以經過 QEMU 爲 I/O 提供便利。QEMU 是一個系統模擬器,它不只提供來賓操做系統虛擬化平臺,還提供整個系統(PCI 主機控制器、磁盤、網絡、視頻硬件、USB 控制器和其餘硬件元素)的模擬。