偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

內(nèi)存虛擬化到底是咋整的?

云計(jì)算 虛擬化
內(nèi)存虛擬化解決虛擬機(jī)里面的進(jìn)程如何訪問(wèn)物理機(jī)上的內(nèi)存這一問(wèn)題。GuestOS本身有虛擬地址空間,用GVA表示。虛擬機(jī)認(rèn)為自己獨(dú)占整個(gè)內(nèi)存空間,用GPA表示。

1. 一句話總結(jié) 

內(nèi)存虛擬化解決虛擬機(jī)里面的進(jìn)程如何訪問(wèn)物理機(jī)上的內(nèi)存這一問(wèn)題。

GuestOS本身有虛擬地址空間,用GVA表示。虛擬機(jī)認(rèn)為自己獨(dú)占整個(gè)內(nèi)存空間,用GPA表示。

HostOS本身有虛擬機(jī)地址空間,用HVA表示。宿主機(jī)本身有物理內(nèi)存空間,用HPA表示。

好,內(nèi)存虛擬化的問(wèn)題變成了GVA->HPA的映射問(wèn)題。

[[228006]]

GVA->GPA通過(guò)GuestOS頁(yè)表映射。HVA->HPA通過(guò)HostOS頁(yè)表映射。因此,只要建立GPA->HVA的映射關(guān)系,即可解決內(nèi)存虛擬化的問(wèn)題。但,這樣三段逐次映射,效率低下。

引入軟件模擬的影子頁(yè)表和硬件輔助的EPT頁(yè)表。

影子頁(yè)表:GuestOS創(chuàng)建GVA->GPA頁(yè)表的時(shí)候,kvm知道GVA對(duì)應(yīng)的HPA,并偷偷記錄下映射關(guān)系GVA->HPA。后續(xù)需要GVA到GPA映射的時(shí)候,根據(jù)影子頁(yè)表就能查到HPA。

EPT頁(yè)表:硬件層面引入EPTP寄存器。直接將Guest的CR3加載到宿主機(jī)的MMU中。同時(shí)EPT頁(yè)表被載入專門的EPT頁(yè)表指針寄存器 EPTP。也就是說(shuō)GVA->GPA->HPA兩次地址轉(zhuǎn)換都由硬件實(shí)現(xiàn)。

2. 概述 

我們知道80386引入了保護(hù)模式后,內(nèi)存空間分為虛擬地址空間和物理地址空間。后續(xù)引入頁(yè)表機(jī)制,把虛擬機(jī)地址送往mmu,mmu查TLB不中的情況下,依次查頁(yè)表就可以找到對(duì)應(yīng)的物理地址。

在虛擬化場(chǎng)景下情況略微復(fù)雜,分為以下幾種:

①GuestOS 虛擬地址(guestOS virtual Adress,GVA)

說(shuō)白了guestos中進(jìn)程使用的虛擬地址就是GVA,也就是程序訪問(wèn)邏輯存儲(chǔ)器的地址。

②guestOS 物理地址(GuestOS Physical Address,GPA)

Guestos認(rèn)為的物理地址,也是虛擬機(jī)mmu查頁(yè)表得出的地址但是他本質(zhì)是一個(gè)邏輯上的地址,是引入虛化后產(chǎn)生的一個(gè)邏輯概念。它必須借助于內(nèi)存虛擬化映射到宿主機(jī)的物理地址上才能訪問(wèn)內(nèi)存

③主機(jī)虛擬機(jī)地址(Host virtul Address,HVA)

宿主機(jī)中的虛擬地址,宿主機(jī)進(jìn)程使用的虛擬地址空間。

④主機(jī)物理地址(Host Physical Address,HPA)

宿主機(jī)真實(shí)內(nèi)存地址,真實(shí)可以訪問(wèn)的物理內(nèi)存空間。

至此,在虛擬機(jī)場(chǎng)景下,如何由GVA->HPA就是內(nèi)存虛擬化的工作。其中,Qemu負(fù)責(zé)管理虛擬機(jī)內(nèi)存大小,記錄內(nèi)存對(duì)應(yīng)的HVA地址(因?yàn)镼emu是用戶態(tài)的進(jìn)程,無(wú)法管理HPA)想要轉(zhuǎn)化為HPA需要借助于KVM內(nèi)核也就是影子頁(yè)表SPT(Shadow Page Table)和EPT(Extent Page Table)

2.1 影子頁(yè)表

在Guestos建立頁(yè)表的時(shí)候,KVM偷偷的建立了一套指向宿主機(jī)物理地址的頁(yè)表??蛻魴C(jī)中的每一個(gè)頁(yè)表項(xiàng)都有一個(gè)影子頁(yè)表項(xiàng)與之相對(duì)應(yīng),就像其影子一樣。

在客戶機(jī)訪問(wèn)內(nèi)存時(shí),真正被裝入宿主機(jī) MMU 的是客戶機(jī)當(dāng)前頁(yè)表所對(duì)應(yīng)的影子頁(yè)表這樣通過(guò)影子頁(yè)表就可以實(shí)現(xiàn)真正的內(nèi)存訪問(wèn)虛擬機(jī)頁(yè)表和影子頁(yè)表通過(guò)一個(gè)哈希表建立關(guān)聯(lián)這樣通過(guò)頁(yè)目錄/頁(yè)表的客戶機(jī)物理地址就可以在哈希鏈表中快速地找到對(duì)應(yīng)的影子頁(yè)目錄/頁(yè)表當(dāng)客戶機(jī)切換進(jìn)程時(shí),客戶機(jī)操作系統(tǒng)會(huì)把待切換進(jìn)程的頁(yè)表基址載入 CR3而 KVM 將會(huì)截獲這一特權(quán)指令,進(jìn)行新的處理,也即在哈希表中找到與此頁(yè)表基址對(duì)應(yīng)的影子頁(yè)表基址,載入客戶機(jī) CR3使客戶機(jī)在恢復(fù)運(yùn)行時(shí) CR3 實(shí)際指向的是新切換進(jìn)程對(duì)應(yīng)的影子頁(yè)表。

2.2 EPT

EPT 技術(shù)在原有客戶機(jī)頁(yè)表對(duì)客戶機(jī)虛擬地址到客戶機(jī)物理地址映射的基礎(chǔ)上引入了 EPT頁(yè)表來(lái)實(shí)現(xiàn)客戶機(jī)物理地址到宿主機(jī)物理地址的另一次映射,這兩次地址映射都是由硬件自動(dòng)完成??蛻魴C(jī)運(yùn)行時(shí),客戶機(jī)頁(yè)表被載入 CR3,而 EPT 頁(yè)表被載入專門的EPT 頁(yè)表指針寄存器 EPTP。

在客戶機(jī)物理地址到宿主機(jī)物理地址轉(zhuǎn)換的過(guò)程中,由于缺頁(yè)、寫權(quán)限不足等原因也會(huì)導(dǎo)致客戶機(jī)退出,產(chǎn)生 EPT異常。對(duì)于 EPT 缺頁(yè)異常,KVM首先根據(jù)引起異常的客戶機(jī)物理地址,映射到對(duì)應(yīng)的宿主機(jī)虛擬地址,然后為此虛擬地址分配新的物理頁(yè)最后 KVM 再更新 EPT 頁(yè)表,建立起引起異常的客戶機(jī)物理地址到宿主機(jī)物理地址之間的映射。對(duì) EPT 寫權(quán)限引起的異常,KVM 則通過(guò)更新相應(yīng)的 EPT 頁(yè)表來(lái)解決。

由此可以看出,EPT 頁(yè)表相對(duì)于前述的影子頁(yè)表,其實(shí)現(xiàn)方式大大簡(jiǎn)化。而且,由于客戶機(jī)內(nèi)部的缺頁(yè)異常也不會(huì)致使客戶機(jī)退出,因此提高了客戶機(jī)運(yùn)行的性能。此外,KVM 只需為每個(gè)客戶機(jī)維護(hù)一套 EPT 頁(yè)表,也大大減少了內(nèi)存的額外開(kāi)銷。

3. Qemu到KVM內(nèi)存管理 

3.1 設(shè)置鉤子 

main(vl.c)==>configure_accelerator==>kvm_init(kvm_all.c)==>memory_listener_register(&kvm_memory_listener,NULL);將kvm_memory_listener添加到memory_listeners鏈表中,將address_spaces和listener建立關(guān)聯(lián)

3.2 內(nèi)存對(duì)象初始化

main(vl.c)==>cpu_exec_init_all(exec.c)==>memory_map_init(exec.c)Qemu中系統(tǒng)內(nèi)存system_memory來(lái)管理,io內(nèi)存用system_io來(lái)管理。static MemoryRegion *system_memory.MemoryRegion可以有子區(qū)域。而memory_lister負(fù)責(zé)處理添加和移除內(nèi)存區(qū)域的管理。

3.3 內(nèi)存實(shí)例化 

pc_init1(hw\pc_piix.c)==>pc_memory_init這里主要分配整個(gè)內(nèi)存區(qū)域重點(diǎn)關(guān)注memory_region_init_ram方法memory_region_init_ram==>qemu_ram_alloc(獲得內(nèi)存的HVA記錄到)==>qemu_ram_alloc_internal==>ram_block_add(生成一個(gè)RAMBlock添加到ram_list,hva放到host字段)==>phys_mem_alloc==>qemu_anon_ram_alloc==>mmap

3.4 VM-Exit處理 

由于mmio導(dǎo)致的退出,相關(guān)處理如下kvm_cpu_exec==> case KVM_EXIT_MMIO==> cpu_physical_memory_rw==> address_space_rw==> io_mem_write

3.5 qemu到kvm的內(nèi)存調(diào)用接口

前面我們講到注冊(cè)過(guò)listener,當(dāng)設(shè)置內(nèi)存時(shí)會(huì)調(diào)用到

static MemoryListener kvm_memory_listener = {

.region_add = kvm_region_add,

region_add==>kvm_region_add==>kvm_set_phys_mem

①物理起始地址和長(zhǎng)度,在kvm_state中搜索已建立的KVMSlot *mem區(qū)域

②如果沒(méi)找到建立一個(gè)slot

==>kvm_set_user_memory_region(通知內(nèi)核態(tài)建立內(nèi)存區(qū)域)==>kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem)

3.6 KVM內(nèi)存處理 

kvm_vm_ioctl==>kvm_vm_ioctl_set_memory_region==>kvm_set_memory_region==>__kvm_set_memory_region內(nèi)核態(tài)也維護(hù)了一個(gè)slots,內(nèi)核態(tài)slot的管理策略是根據(jù)用戶空間的slot_id一一對(duì)應(yīng)的slot =id_to_memslot(kvm->memslots, mem->slot);

①通過(guò)用戶態(tài)的slot獲取到內(nèi)核態(tài)對(duì)應(yīng)結(jié)構(gòu)

②根據(jù)slot中的值和要設(shè)置的值,決定要操作的類別

③根據(jù)2中的動(dòng)作進(jìn)行操作

a.KVM_MR_CREATE: kvm_arch_create_memslot(做了一個(gè)3級(jí)的頁(yè)表)

b.KVM_MR_DELETE OR KVM_MR_MOVE:

申請(qǐng)一個(gè)slots,把kvm->memslots暫存到這里。首先通過(guò)id_to_memslot獲取準(zhǔn)備插入的內(nèi)存條對(duì)應(yīng)到kvm的插槽是slot。無(wú)論刪除還是移動(dòng),將其先標(biāo)記為KVM_MEMSLOT_INVALID。然后是install_new_memslots,其實(shí)就是更新了一下slots->generation的值。

4. EPT相關(guān) 

4.1 EPT初始化 

kvm_arch_init==> kvm_mmu_module_init

①建立pte_list_desc_cache緩存結(jié)構(gòu)

②建立mmu_page_header_cache緩存結(jié)構(gòu),該結(jié)構(gòu)用于kvm_mmu_page

③register_shrinker(&mmu_shrinker);當(dāng)系統(tǒng)內(nèi)存回收被調(diào)用時(shí)的鉤子

vcpu_create==>vmx_create_vcpu==>init_rmode_identity_map==>alloc_identity_pagetable==>__x86_set_memory_region

4.2 EPT載入

vcpu_enter_guest(struct kvm_vcpu *vcpu)==> kvm_mmu_reload(Guest的MMU初始化,為內(nèi)存虛擬化做準(zhǔn)備)==> kvm_mmu_load==>mmu_topup_memory_caches==>mmu_alloc_roots-->mmu_alloc_direct_roots(根據(jù)當(dāng)前vcpu的分頁(yè)模式建立 ept頂層頁(yè)表的管理結(jié)構(gòu))==>kvm_mmu_sync_roots

4.3 gfn_to_page 

該函數(shù)處理GPA的頁(yè)號(hào)到HPA的page結(jié)構(gòu):

  1. gfn_to_page==>gfn_to_pfn==>gfn_to_pfn_memslot==>__gfn_to_pfn_memslot==>__gfn_to_hva_many|hva_to_pfn==>hva_to_pfn_fast|hva_to_pfn_slow 

4.4 分配頁(yè)表

  1. mmu_alloc_roots-->mmu_alloc_direct_roots-->kvm_mmu_get_page-->kvm_mmu_alloc_page 

4.5 EPT vm-entry 

①KVM_REQ_MMU_RELOAD-->kvm_mmu_unload-->mmu_free_roots

②KVM_REQ_MMU_SYNC-->kvm_mmu_sync_roots-->mmu_sync_roots-->mmu_sync_children-->kvm_sync_page-->__kvm_sync_page

③KVM_REQ_TLB_FLUSH-->kvm_vcpu_flush_tlb-->tlb_flush-->vmx_flush_tlb-->__vmx_flush_tlb-->ept_sync_context-->__invept

進(jìn)入非根模式下,根據(jù)不同事件針對(duì)內(nèi)存做相關(guān)處理。

4.6 EPT VM-exit 

①設(shè)置cr3

mmu_alloc_direct_roots中會(huì)分配arch.mmu.root_hpavcpu_enter_guest的時(shí)候會(huì)調(diào)用kvm_mmu_load==> vcpu->arch.mmu.set_cr3(vcpu,vcpu->arch.mmu.root_hpa)這個(gè)函數(shù)要申請(qǐng)內(nèi)存,作為根頁(yè)表使用。同時(shí)root_hpa指向根頁(yè)表的物理地址。然后可以看到,vcpu中cr3寄存器的地址要指向這個(gè)根頁(yè)表的物理地址。

②handle_ept_violation

  1. -->kvm_mmu_page_fault-->arch.mmu.page_fault-->tdp_page_fault 

__direct_map 這個(gè)函數(shù)是根據(jù)傳進(jìn)來(lái)的gpa進(jìn)行計(jì)算,從第4級(jí)(level-4)頁(yè)表頁(yè)開(kāi)始,一級(jí)一級(jí)地填寫相應(yīng)頁(yè)表項(xiàng)這些都是在for_each_shadow_entry(vcpu, (u64)gfn << PAGE_SHIFT, iterator) 這個(gè)宏定義里面實(shí)現(xiàn)的.這兩種情況是這樣子的:

a.如果當(dāng)前頁(yè)表頁(yè)的層數(shù)(iterator.level )是最后一層( level )的頁(yè)表頁(yè),那么直接通過(guò)調(diào)用 mmu_set_spte (之后會(huì)細(xì)講)設(shè)置頁(yè)表項(xiàng)。

b.如果當(dāng)前頁(yè)表頁(yè) A 不是最后一層,而是中間某一層(leve-4, level-3, level-2)

而且該頁(yè)表項(xiàng)之前并沒(méi)有初始化(!is_shadow_present_pte(*iterator.sptep) )那么需要調(diào)用kvm_mmu_get_page 得到或者新建一個(gè)頁(yè)表頁(yè) B然后通過(guò) link_shadow_page 將其link到頁(yè)表頁(yè) A 相對(duì)應(yīng)的頁(yè)表項(xiàng)中

4.7 EPT遍歷操作

for_each_shadow_entry這個(gè)是定義在mmu.c中的一個(gè)宏,用來(lái)不斷的遍歷頁(yè)表的層級(jí)。

4.8 影子頁(yè)表 

init_kvm_mmu==>init_kvm_softmmu

在上述的ept的過(guò)程中,根據(jù)參數(shù)不同會(huì)有不同分支大體邏輯保持一致,毋庸贅言。

 

責(zé)任編輯:武曉燕 來(lái)源: 騰訊云TStack
相關(guān)推薦

2018-12-09 16:52:01

無(wú)線充電無(wú)線

2023-10-10 16:03:48

數(shù)字化信息化

2016-11-17 22:18:31

id串行化服務(wù)器

2024-02-22 08:00:00

SoraOpenAI

2022-08-08 08:00:00

人工智能機(jī)器學(xué)習(xí)計(jì)算機(jī)應(yīng)用

2022-06-07 23:33:53

數(shù)字化轉(zhuǎn)型企業(yè)轉(zhuǎn)型數(shù)字化

2025-10-29 07:33:13

2022-05-24 17:00:41

區(qū)塊鏈IT比特幣

2013-11-18 10:34:00

企業(yè)移動(dòng)化移動(dòng)信息化

2024-03-15 08:06:58

MySQLJOIN命令

2016-08-04 14:53:34

服務(wù)器虛擬化網(wǎng)絡(luò)

2015-04-21 09:20:40

SwfitObject—C

2025-10-31 00:00:02

硅光光通信英偉達(dá)

2021-02-05 10:03:31

區(qū)塊鏈技術(shù)智能

2013-04-24 09:08:17

Google眼鏡

2020-08-19 07:48:11

云計(jì)算亞馬遜搜索

2019-05-28 13:50:27

MySQL幻讀數(shù)據(jù)庫(kù)

2022-08-12 08:03:59

算力網(wǎng)絡(luò)算力網(wǎng)絡(luò)

2010-04-02 16:46:43

云計(jì)算

2021-08-13 05:47:48

通信設(shè)計(jì)院通信行業(yè)設(shè)計(jì)院
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)