最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

深入分析Linux虛擬化KVM-Qemu之ARMv8虛擬化

2022-12-30 15:44 作者:補(bǔ)給站Linux內(nèi)核  | 我要投稿

說明:

  1. KVM版本:5.9.1

  2. QEMU版本:5.0.0

  3. 工具:Source Insight 3.5, Visio

1. 概述

圖片
  • KVM虛擬化離不開底層硬件的支持,本文將介紹ARMv8架構(gòu)處理器對(duì)虛擬化的支持,包括內(nèi)存虛擬化、中斷虛擬化、I/O虛擬化等內(nèi)容;

  • ARM處理器主要用于移動(dòng)終端領(lǐng)域,近年也逐漸往服務(wù)器領(lǐng)域靠攏,對(duì)虛擬化也有了較為完善的支持;

  • Hypervisor軟件,涵蓋的功能包括:內(nèi)存管理、設(shè)備模擬、設(shè)備分配、異常處理、指令捕獲、虛擬異常管理、中斷控制器管理、調(diào)度、上下文切換、內(nèi)存轉(zhuǎn)換、多個(gè)虛擬地址空間管理等;

  • 本文描述的ARMv8虛擬化支持,對(duì)于理解arch/arm64/kvm下的代碼很重要,脫離硬件去看Architecture-Specific代碼,那是耍流氓;

開始旅程!

2. ARMv8虛擬化

2.1 Exception Level

  • ARMv7之前的架構(gòu),定義了一個(gè)處理器的異常處理模式,比如USR, FIQ, IRQ, SVC, ABT, UND, SYS, HYP, MON等,各個(gè)異常模式所處的特權(quán)級(jí)不一樣,比如USR模式的特權(quán)級(jí)就為PL0,對(duì)應(yīng)為用戶態(tài)程序運(yùn)行;

  • 處理器的異常模式可以在特權(quán)級(jí)軟件控制下進(jìn)行主動(dòng)切換,比如修改CPSR寄存器,也可以被動(dòng)進(jìn)行異常模式切換,典型的比如中斷來臨時(shí)切換到IRQ模式

ARMv7處理器的異常模式如下表所示:

圖片

然鵝,到了ARMv8,Exception Level(EL)取代了特權(quán)級(jí),其中處理器的異常模式與Exception Level的映射關(guān)系如下圖:

圖片
  • 當(dāng)異常發(fā)生時(shí),處理器將改變Exception Level(相當(dāng)于ARMv7中的處理器模式切換),來處理異常類型;

  • 圖中可以看出Hypervisor運(yùn)行在EL2,而Guest OS運(yùn)行在EL1,可以通過HVC (Hypervisor Call)指令向Hypervisor請(qǐng)求服務(wù),響應(yīng)虛擬化請(qǐng)求時(shí)就涉及到了Exception Level的切換;


【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【749907784】整理了一些個(gè)人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實(shí)戰(zhàn)項(xiàng)目及代碼)? ??

2.2 Stage 2 translation

Stage 2轉(zhuǎn)換與內(nèi)存虛擬化息息相關(guān),這部分內(nèi)容不僅包括常規(guī)的內(nèi)存映射訪問,還包含了基于內(nèi)存映射的I/O(MMIO)訪問,以及系統(tǒng)內(nèi)存管理單元(SMMUs)控制下的內(nèi)存訪問。

2.2.1 內(nèi)存映射

OS在訪問物理內(nèi)存前,需要先建立頁表來維護(hù)虛擬地址到物理地址的映射關(guān)系,看過之前內(nèi)存管理分析的同學(xué)應(yīng)該熟悉下邊這張圖,這個(gè)可以認(rèn)為是Stage 1轉(zhuǎn)換

圖片
  • 當(dāng)有了虛擬機(jī)時(shí),情況就不太一樣了,比如Qemu運(yùn)行在Linux系統(tǒng)之上時(shí),它只是Linux系統(tǒng)的一個(gè)用戶進(jìn)程,Guest OS所認(rèn)為自己訪問的物理地址,其實(shí)是Linux的用戶進(jìn)程虛擬地址,到最終的物理地址還需要進(jìn)一步的映射;

  • Hypervisor可以通過Stage 2轉(zhuǎn)換來控制虛擬機(jī)的內(nèi)存視圖,控制虛擬機(jī)是否可以訪問某塊物理內(nèi)存,進(jìn)而達(dá)到隔離的目的;

圖片
  • 整個(gè)地址的映射分成了兩個(gè)階段:

    1. Stage 1: VA(Virutal Address) -> IPA(Intermediate Physical Address),操作系統(tǒng)控制Stage 1轉(zhuǎn)換;

    2. Stage 2: IPA(Intermediate Physical Address) -> PA(Physical Address),Hypervisor控制Stage 2轉(zhuǎn)換;

  • Stage 2轉(zhuǎn)換Stage 1轉(zhuǎn)換機(jī)制很類似,不同點(diǎn)在于Stage 2轉(zhuǎn)換時(shí)判斷內(nèi)存類型是normal還是device時(shí),是存放進(jìn)頁表信息里了,而不是通過MAIR_ELx寄存器來判斷;

  • 每個(gè)虛擬機(jī)(VM,Virtual Machine)都會(huì)分配一個(gè)VMID,用于標(biāo)識(shí)TLB entry所屬的VM,允許在TLB中同時(shí)存在多個(gè)不同VM的轉(zhuǎn)換;

  • 操作系統(tǒng)會(huì)給應(yīng)用程序分配一個(gè)ASID(Address Space Identifier),也可以用于標(biāo)識(shí)TLB entry,屬于同一個(gè)應(yīng)用程序的TLB entry都有相同的ASID,不同的應(yīng)用程序可以共享同一塊TLB緩存。每個(gè)VM都有自己的ASID空間,通常會(huì)結(jié)合VMIDASID來同時(shí)使用;

  • Stage 1Stage 2的轉(zhuǎn)換頁表中,都包含了屬性的相關(guān)設(shè)備,比如訪問權(quán)限,存儲(chǔ)類型等,在兩級(jí)轉(zhuǎn)換的過程中,MMU會(huì)整合成一個(gè)最終的也有效值,選擇限制更嚴(yán)格的屬性,如下圖:

圖片
  • 圖中的Device屬性限制更嚴(yán)格,則選擇Device類型;

  • Hypervisor如果想要改變默認(rèn)整合行為,可以通過寄存器HCR_EL2(Hypervisor Configuration Register)來配置,比如設(shè)置Non-cacheable,?Write-Back Cacheable等特性;

2.2.2?MMIO(Memory-Mapped Input/Output)

Guest OS認(rèn)為的物理地址空間,實(shí)際是IPA地址空間,就像真實(shí)物理機(jī)中一樣,IPA的地址空間,也分成內(nèi)存地址空間和I/O地址空間:

圖片
  • 訪問外設(shè)有兩種情況:1)直通訪問真實(shí)的外設(shè);2)觸發(fā)faultHypervisor通過軟件來模擬;

  • VTTBR_EL2Virtualization Translation Table Base Register,虛擬轉(zhuǎn)換表基地址寄存器,存放Stage 2轉(zhuǎn)換的頁表;

  • 為了模擬外設(shè),Hypervisor需要知道訪問的是哪個(gè)外設(shè)以及訪問的寄存器,讀訪問還是寫訪問,訪問長(zhǎng)度是多少,使用哪些寄存器來傳送數(shù)據(jù)等。Stage 2轉(zhuǎn)換有一個(gè)專門的Hypervisor IPA Fault Address Register, EL2(HPFAR_EL2)寄存器,用于捕獲Stage 2轉(zhuǎn)換過程中的fault;

軟件模擬外設(shè)的示例流程如下:

圖片
  • 1)虛擬機(jī)VM中的軟件嘗試訪問串口設(shè)備;

  • 2)訪問時(shí)Stage 2轉(zhuǎn)換被block住,并觸發(fā)abort異常路由到EL2。異常處理程序查詢ESR_EL2(Exception Syndrome Register)寄存器關(guān)于異常的信息,如訪問長(zhǎng)度、目標(biāo)寄存器,Load/Store操作等,異常處理程序還會(huì)查詢HPFAR_EL2寄存器,獲取abort的IPA地址;

  • 3)Hypervisor通過ESR_EL2HPFAR_EL2里的相關(guān)信息對(duì)相關(guān)虛擬外圍設(shè)備進(jìn)行模擬,完成后通過ERET指令返回給vCPU,從發(fā)生異常的下一條指令繼續(xù)運(yùn)行;

2.2.3?SMMUs(System Memory Management Units)

訪問內(nèi)存的另外一種case就是DMA控制器。

非虛擬化下DMA控制器的工作情況如下:

圖片
  • DMA控制器由內(nèi)核的驅(qū)動(dòng)程序來控制,能確保操作系統(tǒng)層面的內(nèi)存的保護(hù)不會(huì)被破壞,用戶程序無法通過DMA去訪問被限制的區(qū)域;

虛擬化下DMA控制器,VM中的驅(qū)動(dòng)直接與DMA控制器交互會(huì)出現(xiàn)什么問題呢?如下圖:

圖片
  • DMA控制器不受Stage 2轉(zhuǎn)換的約束,會(huì)破壞VM的隔離性;

  • Guest OS以為的物理地址是IPA地址,而DMA看到的地址是真實(shí)的物理地址,兩者的視角不一致,為了解決這個(gè)問題,需要捕獲每次VM與DMA控制器的交互,并提供轉(zhuǎn)換,當(dāng)內(nèi)存出現(xiàn)碎片化時(shí),這個(gè)處理低效且容易引入問題;

SMMUs可以用于解決這個(gè)問題:

圖片
  • SMMU也叫IOMMU,對(duì)IO部件提供MMU功能,虛擬化只是SMMU的一個(gè)應(yīng)用;

  • Hypervisor可以負(fù)責(zé)對(duì)SMMU進(jìn)行編程,以便讓上層的控制器和虛擬機(jī)VM以同一個(gè)視角對(duì)待內(nèi)存,同時(shí)也保持了隔離性;

2.3 Trapping and emulation of Instructions

Hypervisor也需要具備捕獲(trap)和模擬指令的能力,比如當(dāng)VM中的軟件需要配置底層處理器來進(jìn)行功耗管理或者緩存一致性操作時(shí),為了不破壞隔離性,Hypervisor就需要捕獲操作并進(jìn)行模擬,以便不影響其他的VM。如果設(shè)置了捕獲某個(gè)操作時(shí),當(dāng)該操作被執(zhí)行時(shí)會(huì)向更高一級(jí)的Exception Level觸發(fā)異常(比如Hypervisor為EL2),從而在相應(yīng)的異常處理中完成模擬。

例子來了:

圖片
  • 在ARM處理器中執(zhí)行WFI(wait for interrupt)命令,可以讓CPU處于一個(gè)低功耗的狀態(tài);

  • HCR_EL2(Hypervisor Control Register),當(dāng)該寄存器的TWI==1時(shí),vCPU執(zhí)行WFI指令會(huì)觸發(fā)EL2異常,從而Hypervisor可以對(duì)其進(jìn)行模擬,將任務(wù)調(diào)度到另外一個(gè)vCPU即可;

捕獲(traps)的另一個(gè)作用是可以用于向Guest OS呈現(xiàn)寄存器的虛擬值,如下:

圖片
  • ID_AA64MMFR0_EL1寄存器用于查詢處理器對(duì)內(nèi)存系統(tǒng)相關(guān)特性的支持,系統(tǒng)可能在啟動(dòng)階段會(huì)讀取該寄存器,Hypervisor可以向Guest OS呈現(xiàn)一個(gè)不同的虛擬值;

  • 當(dāng)vCPU讀取該寄存器時(shí),觸發(fā)異常,Hypervisortrap_handler中進(jìn)行處理,設(shè)置一個(gè)虛擬值,并最終返回給vCPU;

  • 通過trap來虛擬化一個(gè)操作需要大量的計(jì)算,包括觸發(fā)異常、捕獲,模擬、返回等一系列操作,像ID_AA64MMFR0_EL1寄存器訪問并不頻繁,這種方式問題不大。但是當(dāng)需要頻繁訪問的寄存器,比如MIDR_EL1MPIDR_EL1等,出于性能的考慮,應(yīng)該避免陷入到Hypervisor中進(jìn)行模擬處理,可以通過其他機(jī)制,比如提供VPIDR_EL2VMIDR_EL2寄存器,在進(jìn)入VM前就設(shè)置好該值,當(dāng)讀取MIDR_EL1MPIDR_EL1時(shí),硬件就返回VPIDR_EL2VMIDR_EL2的值,避免了陷入處理;

2.4 Virtualizing exceptions

  • Hypervisor對(duì)虛擬中斷的處理比較復(fù)雜,Hypervisor本身需要機(jī)制來在EL2處理中斷,還需要機(jī)制來將外設(shè)的中斷信號(hào)發(fā)送到目標(biāo)虛擬機(jī)VM(或vCPU)上,為了使能這些機(jī)制,ARM體系架構(gòu)包含了對(duì)虛擬中斷的支持(vIRQs,vFIQs,vSErrors);

  • 處理器只有在EL0/EL1執(zhí)行狀態(tài)下,才能收到虛擬中斷,在EL2/EL3狀態(tài)下不能收到虛擬中斷;

  • Hypervisor通過設(shè)置HCR_EL2寄存器來控制向EL0/EL1發(fā)送虛擬中斷,比如為了使能vIRQ,需要設(shè)置HCR_EL2.IMO,設(shè)置后便會(huì)將物理中斷發(fā)送至EL2,然后使能將虛擬中斷發(fā)送至EL1;

有兩種方式可以產(chǎn)生虛擬中斷:1)在處理器內(nèi)部控制HCR_EL2寄存器;2)通過GIC中斷控制器(v2版本以上);其中方式一使用比較簡(jiǎn)單,但是它只提供了產(chǎn)生中斷的方式,需要Hypervisor來模擬VM中的中斷控制器,通過捕獲然后模擬的方式,會(huì)帶來overhead,當(dāng)然不是一個(gè)最優(yōu)解。

讓我們來看看GIC吧,看過之前中斷子系統(tǒng)系列文章的同學(xué),應(yīng)該見過下圖:

圖片
  • Hypervisor可以將GIC中的Virtual CPU Interface映射到VM中,從而允許VM中的軟件直接與GIC進(jìn)行通信,Hypervisor只需要進(jìn)行配置即可,這樣可以減少虛擬中斷的overhead;

來個(gè)虛擬中斷的例子吧:

圖片
  1. 外設(shè)觸發(fā)中斷信號(hào)到GIC;

  2. GIC產(chǎn)生物理中斷IRQ或者FIQ信號(hào),如果設(shè)置了HCR_EL2.IMO/FMO,中斷信號(hào)將被路由到Hypervisor,Hypervisor會(huì)檢查中斷信號(hào)轉(zhuǎn)發(fā)給哪個(gè)vCPU;

  3. Hypervisor設(shè)置GIC,將該物理中斷信號(hào)以虛擬中斷的形式發(fā)送給某個(gè)vCPU,如果此時(shí)處理器運(yùn)行在EL2,中斷信號(hào)會(huì)被忽略;

  4. Hypervisor將控制權(quán)返回給vCPU;

  5. 處理器運(yùn)行在EL0/EL1時(shí),虛擬中斷會(huì)被接受和處理

  • ARMv8處理器中斷屏蔽由PSTATE中的比特位來控制(比如PSTATE.I),虛擬化時(shí)比特位的作用有些不一樣,比如設(shè)置HCR_EL2.IMO時(shí),表明物理IRQ路由到EL2,并且對(duì)EL0/EL1開啟vIRQs,因此,當(dāng)運(yùn)行在EL0/EL1時(shí),PSTATE.I比特位針對(duì)的是虛擬vIRQs而不是物理的pIRQs。

2.5 Virtualizing the Generic Timers

先來看一下SoC的內(nèi)部:

圖片

簡(jiǎn)化之后是這樣的:

圖片
  • ARM體系架構(gòu)每個(gè)處理器都包含了一組通用定時(shí)器,從圖中可以看到兩個(gè)模塊:ComparatorsCounter Module,當(dāng)Comparators的值小于等于系統(tǒng)的count值時(shí)便會(huì)產(chǎn)生中斷,我們都知道在操作系統(tǒng)中timer的中斷就是系統(tǒng)的脈搏了;

下圖展示虛擬化系統(tǒng)中運(yùn)行的vCPU的時(shí)序:

圖片
  • 物理時(shí)間4ms,每個(gè)vCPU運(yùn)行2ms,如果設(shè)置vCPU0T=0之后的3ms后產(chǎn)生中斷,那希望是物理時(shí)間的3ms后(也就是vCPU0的虛擬時(shí)間2ms)產(chǎn)生中斷,還是虛擬時(shí)間3ms后產(chǎn)生中斷?ARM體系結(jié)構(gòu)支持這兩種設(shè)置;

  • 運(yùn)行在vCPU上的軟件可以同時(shí)訪問兩種時(shí)鐘:EL1物理時(shí)鐘EL1虛擬時(shí)鐘;

EL1物理時(shí)鐘EL1虛擬時(shí)鐘

圖片
  • EL1物理時(shí)鐘與系統(tǒng)計(jì)數(shù)器模塊直接比較,使用的是wall-clock時(shí)間;

  • EL1虛擬時(shí)鐘與虛擬計(jì)數(shù)器比較,而虛擬計(jì)數(shù)器是在物理計(jì)數(shù)器上減去一個(gè)偏移;

  • Hypervisor負(fù)責(zé)為當(dāng)前調(diào)度運(yùn)行的vCPU指定對(duì)應(yīng)的偏移,這種方式使得虛擬時(shí)間只會(huì)覆蓋vCPU實(shí)際運(yùn)行的那部分時(shí)間;

來一張示例圖:

圖片
  • 6ms的時(shí)間段里,每個(gè)vCPU運(yùn)行3ms,Hypervisor可以使用偏移寄存器來將vCPU的時(shí)間調(diào)整為其實(shí)際的運(yùn)行時(shí)間;

2.6 Virtualization Host Extensions(VHE)

  • 先拋出一個(gè)問題:通常Host OS的內(nèi)核都運(yùn)行在EL1,而控制虛擬化的代碼運(yùn)行在EL2,這就意味著傳統(tǒng)的上下文切換,這個(gè)顯然是比較低效的;

  • VHE用于支持type-2Hypervisor,這種擴(kuò)展可以讓內(nèi)核直接跑在EL2,減少host和guest之間共享的系統(tǒng)寄存器數(shù)量,同時(shí)也減少虛擬化的overhead;

VHE由系統(tǒng)寄存器HCR_EL2E2HTGE兩個(gè)比特位來控制,如下圖:

圖片

VHE的引入,需要考慮虛擬地址空間的問題,如下圖:

圖片
  • 我們?cè)趦?nèi)存子系統(tǒng)分析時(shí)提到過虛擬地址空間的問題,分為用戶地址空間(EL0)和內(nèi)核地址空間(EL1),兩者的區(qū)域不一致,而在EL2只有一個(gè)虛擬地址空間區(qū)域,這是因?yàn)?code>Hypervisor不支持應(yīng)用程序,因此也就不需要分成內(nèi)核空間和用戶空間了;

  • EL0/EL1虛擬地址空間也同時(shí)支持ASID(Address Space Identifiers),而EL2不支持,原因也是Hypervisor不需要支持應(yīng)用程序;

從上兩點(diǎn)可以看出,為了支持Host OS能運(yùn)行在EL2,需要添加一個(gè)地址空間區(qū)域,以及支持ASID,設(shè)置HCR_EL2.E2H的寄存器位可以解決這個(gè)問題,如下圖:

圖片

Host OS運(yùn)行在EL2需要解決的另一個(gè)問題就是寄存器訪問重定向,在內(nèi)核中需要訪問EL1的寄存器,比如TTBR0_EL1,而當(dāng)內(nèi)核運(yùn)行在EL2時(shí),不需要修改內(nèi)核代碼,可以通過寄存器的設(shè)置來控制訪問流,如下圖:

圖片
  • 重定向訪問寄存器引入一個(gè)新的問題,Hypervisor在某些情況下需要訪問真正的EL1寄存器,ARM架構(gòu)引入了一套新的別名機(jī)制,以_EL12/_EL02結(jié)尾,如下圖,可以在ECH==1EL2訪問TTBR0_EL1

圖片

Host OS運(yùn)行在EL2還需要考慮異常處理的問題,前邊提到過HCR_EL2.IMO/FMO/AMO的比特位可以用來控制物理異常路由到EL1/EL2。當(dāng)運(yùn)行在EL0TGE==1時(shí),所有物理異常都會(huì)被路由到EL2(除了SCR_EL3控制的),這是因?yàn)?code>Host Apps運(yùn)行在EL0,而Host OS運(yùn)行在EL2。

2.7 總結(jié)

  • 本文涉及到內(nèi)存虛擬化(stage 2轉(zhuǎn)換),I/O虛擬化(包含了SMMU,中斷等),中斷虛擬化,以及指令trap and emulation等內(nèi)容;

  • 基本的套路就是請(qǐng)求虛擬化服務(wù)時(shí),路由到EL2去處理,如果有硬件支持的則硬件負(fù)責(zé)處理,否則可以通過軟件進(jìn)行模擬;

原文作者:LoyenWang





深入分析Linux虛擬化KVM-Qemu之ARMv8虛擬化的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
土默特左旗| 三亚市| 新乡县| 孟连| 孟州市| 西宁市| 三亚市| 特克斯县| 许昌县| 政和县| 密山市| 青河县| 平远县| 军事| 南皮县| 霍林郭勒市| 凉城县| 山西省| 根河市| 阿巴嘎旗| 塘沽区| 墨江| 山阳县| 雷山县| 库车县| 文山县| 晋宁县| 根河市| 治县。| 天长市| 正镶白旗| 重庆市| 嵩明县| 吉林市| 静乐县| 河北省| 云南省| 汽车| 咸丰县| 农安县| 广丰县|