天天看點

VMCS研究總結

再來看kvm配置設定與初始化vmcs的代碼路徑。我發現有兩個路徑都是要配置設定vmcs的: 第一是kvm核心子產品加載時,在hardware_setup中調用alloc_kvm_area,進而對每一個cpu調用alloc_vmcs_cpu。這裡的每一個cpu應該是實體cpu了,為什麼要對每個實體cpu都配置設定一個頁的vmcs空間覺得有點奇怪,還沒想明白。另外,setup_vmcs_config很重要,是kvm預設對vmcs的一些配置,第三部分再講,要注意的是它隻是将配置記錄到額外的一個結構vmcs_config中,并沒有真正就寫入vmcs了,後面真正寫vmcs會用到這個結構。 vmx_init(vmx.c)       |   kvm_init(kvm_main.c)       |   kvm_arch_init(kvm_main.c) --> kvm_arch_hardware_setup       |                                                            |   kvm_timer_init(x86.c)           kvm_x86_ops->hardware_setup(vmx.c)                                                                    |                                                setup_vmcs_config(vmx.c)  --> alloc_kvm_area(vmx.c)                                                                                                        | for_each_cpu                                                                                           alloc_vmcs_cpu(vmx.c)   第二是建立vcpu時,因為每個vcpu應該要單獨對應一個vmcs。可以看到,這裡也是用alloc_vmcs_cpu配置設定一個頁的vmcs,是以我就覺得奇怪,既然每個vcpu都配置設定了vmcs頁,為什麼pcpu也要每個都配置設定一個vmcs頁,不是可以像頁表那樣,用一個寄存器指向目前vcpu的vmcs頁就行了麼?另外,vmx_vcpu_setup很重要,它是真正地将配置寫入vmcs頁中去了。 KVM_CREATE_VCPU ---> kvm_vm_ioctl (kvm_main.c)                                                 |                 kvm_vm_ioctl_create_vcpu(kvm_main.c)   | kvm_arch_vcpu_create(x86.c)   |    kvm_x86_ops->vcpu_create(vmx_create_vcpu in vmc.c)                                    |                        alloc_vmcs(vmx.c)   --->   vmx_vcpu_setup                                   |                                   |                       alloc_vmcs_cpu(vmx.c)     vmcs_writel  -->  guest_write_tsc 最後來看kvm對vmcs的一些重要配置。它幾個部分的配置比較的分散: IO bitmap A and B在vmx_init中配置,畢竟vmcs中記錄的隻是IO bitmap的實體位址。具體的配置這裡就不說了。 我現在關心的vmcs配置是:VM execution control、VM entry control及VM exit control三個部分。它們的具體配置是在setup_vmcs_config(注意這個是通用配置,後面特定的vcpu可以有修改),其中重要的設定有: 1. PIN_BASED_EXT_INTR_MASK;标志着external interrupt會導緻VMExit; 2. 沒有RDTSC_EXITING;标志着rdtsc指令不會導緻VMExit,guest可以直接讀取實體TSC; 3. CPU_BASED_USE_TSC_OFFSETTING;标志着讀取的實體TSC還要加上一個TSC_OFFSET才得到guest TSC; 4. CPU_BASED_USE_IO_BITMAPS;标志着每個guest IO指令産不産生VMExit要去查IO bitmap; 5. SECONDARY_EXEC_ENABLE_EPT;标志着預設是打開ept特性的;6. 沒有VM_EXIT_ACK_INTR_ON_EXIT;我的了解是這樣的—原來在guest模式下,中斷是關閉的,但是會導緻VMExit(上1配置)。Exit後kvm核心代碼立刻開中斷,這時必須能檢測到這個中斷。如果VMExit時就自動ack了,再開中斷時就檢測不到這個中斷了。 7. 1-6都是Execution control,至于Entry和Exit control在setup_vmcs_config中固定配置比較少,現在也不太關心,以後再總結。