2019年3月23日 星期六

淺談Intel Virtual Machine Extensions(VMX)

VMX主要是由Intel所定義的architecture,可以再 "Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3B: System Programming Guide, Part 2" 這分文件的Chapter19去詳細了解,文中都是對於spec的翻譯或者是自己的見解,如果有誤還請多指教。


■ VMX Architecture


VMX是CPU的virtualization,主要定義了兩個角色:


Virtual-machine monitors (VMM): 扮演著Host的腳色,擁有CPU所有的控制權,VMM 可以透過guest software虛擬出virtual CPU,並且可以直接讓logical CPU直接執行。


Guest Software:  或稱Virtual Machine(簡稱VM)。每一個VM都是獨立運行的,而且VM運行的時候,VM並不會知道有VMM的存在,他可以直接運行在現有的OS種類,例如: Win7, Ubuntu等等。而在VM必須運行在reduced privilege level(較低的特權等級),這是為了讓VMM可以完全控制VM。


■ CPU Privilege level


提到CPU的privilege level,就要參考到Intel 64 and IA-32 的manual。CPU的privilege 可以分為4個level(如下圖,截圖至Intel spec),分別為ring0到ring3,ring0的特權最高,通常是給比較critical的software所使用,例如Linux的kernel mode,ring3的特權最低,例如Linux的User Mode。




■  VMX Instructions

VMX定意了兩種模式,分別為Root modeNon-root mode,VMM會運行在root mode,VM則運行在non root mode。
接下來介紹幾個VMX operation的指令,由下圖所示,
  • Software可以透過執行VMXON指令來進入VMX operation。
  • VMM可以透過 VMLAUNCH 和 VMRESUME 指令讓guest進入non root mode,這個行為叫作VM entries
  • 當VM運行在non root mode,可能會因為特殊的event讓VM切換回root mode,這個行為叫作VM exits
  • 最終,VMM可以決定要離開VMX operation,VMM則會執行VMXOFF指令來離開。


■ Discovered Support of VMX

要如何知道目前平台的CPU有沒有支援VMX的功能呢?我們可以透過CPUID.1:ECX.VMX[bit 5] = 1來得知CPU有support VMX operation。

補充: CPUID.1:ECX.VMX[bit 5] 的意思就是將CPU暫存器EAX設為1,然後執行CPUID指令,結果會反應在暫存器ECX上。



■ Enable VMX operation

Check CPU有support VMX後,必須要enable VMX,Enable的方法需要設置兩個CPU MSR,分別為CR4.VMXE[13]IA32_FEATURE_CONTROL[2][0](如下圖所示)。





■ VMXON region

在所有的Enable bit都設置起來後,就可以執行VMXON指令,但在執行VMXON之前,software必須allocate一塊4K -byte alignment的memory,並且把這塊memory的base address做為VMXON的運算元(operand),以下為KVM code的範例

//kvm vmx.c
static void kvm_cpu_vmxon(u64 addr)
 {
 asm volatile (ASM_VMX_VMXON_RAX
 : : "a"(&addr), "m"(addr)
 : "memory", "cc");
}

■ Virtual Machine Control Structure(VMCS)

VMCS是整個VMX的核心,這個結構用來管理,VM entries和VM exits所要存放的資料。
VMM可能會管理很多個VMCSs,但每一個logical processor (virtual processor)只會使用一個VMCS,稱為VMCS region,每一個VMCS region都會佔memory的一部份。

指令:
  • 透過執行VMPTRLD(Pointer load)指令讓VMCS狀態轉變為Active,VMPTRLD必須傳入VMCS region的base address的參數。
  • 當執行VMPTRLD後,此VMCS會被load到current-VMCS pointer,此目的是為了VMM可以知道當前的VMCS region為哪一個。
  • VMPTRST(Pointer store)則是將current VMCS pointer裡的address放在某一個memory 的位置。
  • 透過執行VMCLEAR指令讓VMCS狀態轉變為Inactive。
  • 透過執行VMREAD, VMWRITE來對VMCS region讀寫。

■ Format of VMCS

VMCS結構可以分為三個部份:
  • VMCS revision identifier: 由於上述提到VMM可能會管理多個VMCSs結構,所以必須要使用一個特別的號碼來代表每一個VMCS 
  • VMX abort indicator: 當有發生一些配置錯誤造成failure,VM則會寫入非零值,但VM只會寫入這個區塊,並不會讀取這個區塊
  • VMCS data: 在VMCS data裡又可以細分為六個區域
    1. Guest state area: 如果發生VM-exit的話CPU的state會被save到guest-state area,在VM-enrties時則是被載入到CPU中
    2. Host-state area: 在VM exit的時候,處理器的狀態會被載入到host-state area
    3. VM-execution control fields: 當CPU運行在non-root mode的時候,用來控制一些non root mode的行為
    4. VM-exit control: 控制CPU在處理VM-exit時的行為
    5. VM-entry control: 控制CPU在處理VM-entry時的行為
    6. VM-exit information fields: 紀錄VM-exit 事件的原因及相關的訊息,也會記錄VMX指令fail後的error code,為read only

Reference: Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3B: System Programming Guide, Part 2

沒有留言:

張貼留言

解析 NVM Express - 透過Linux OS 解析M.2 NVMe SSD

在之前,我撰寫了三篇有關NVMe的文章 ,分別是" 原理NVM Express - NVMe Submission Queue & Completion Queue (SQ & CQ) "、" 原理NVM Express - Admi...