ARM GIC 虚拟化学习笔记【转】
轉(zhuǎn)自:https://stdrc.cc/post/2020/09/26/arm-gic-virtualization/
這是一篇學(xué)習(xí)過(guò)程中的筆記,因?yàn)闀r(shí)間原因不再組織成流暢的語(yǔ)言,而是直接分享了~
References
Linux 4.2.1(最新的 5.8 相比 4.2 更抽象,不便于理解邏輯)
arch/arm64/kvm/
virt/kvm/arm/
https://mp.weixin.qq.com/s/GI4nV7URCU5Oem6hmVee2Q
https://www.linux-kvm.org/images/7/79/03x09-Aspen-Andre_Przywara-ARM_Interrupt_Virtualization.pdf
ARM GIC Architecture Specification, v2 & v3
GICv2
Non-virtualization
中斷進(jìn)入 distributor,然后分發(fā)到 CPU interface
某個(gè) CPU 觸發(fā)中斷后,讀 GICC_IAR 拿到中斷信息,處理完后寫 GICC_EOIR 和 GICC_DIR(如果 GICC_CTLR.EOImodeNS 是 0,則 EOI 的同時(shí)也會(huì) DI)
GICD、GICC 寄存器都是 MMIO 的,device tree 中會(huì)給出物理地址
Virtualization
HCR_EL2.IMO 設(shè)置為 1 后,所有 IRQ 都會(huì) trap 到 HYP
HYP 判斷該 IRQ 是否需要插入到 vCPU
插入 vIRQ 之后,在切換到 VM 之前需要 EOI 物理 IRQ,即 priority drop,降低運(yùn)行優(yōu)先級(jí),使之后 VM 運(yùn)行時(shí)能夠再次觸發(fā)該中斷
回到 VM 后,GIC 在 EL1 觸發(fā) vIRQ,這時(shí)候 EOI 和 DI 會(huì)把 vIRQ 和物理 IRQ 都 deactivate,因此不需要再 trap 到 HYP,不過(guò)如果是 SGI 的話并不會(huì) deactivate,需要 HYP 自己處理(通過(guò) maintenance 中斷?)
HYP interface (GICH)
GICH base 物理地址在 device tree 中給出
控制寄存器:GICH_HCR、GICH_VMCR 等
List 寄存器:GICH_LRn
KVM 中,這些寄存器保存在struct vgic_cpu的vgic_v2字段,struct vgic_cpu本身放在struct kvm_vcpu_arch,每個(gè) vCPU 一份
vCPU switch 的時(shí)候,需要切換這些寄存器(KVM 在vgic-v2-switch.S中定義相關(guān)切換函數(shù))
VM 無(wú)法訪問(wèn) GICH 寄存器,因?yàn)楦緵](méi)有映射
List register (LR)
vCPU interface (GICV, GICC in VM's view)
GICV 也是物理 GIC 上存在的,base 物理地址同樣在 device tree 中給出
KVM 在系統(tǒng)全局的一個(gè)結(jié)構(gòu)體(struct vgic_params vgic_v2_params)保存了這個(gè)物理地址
創(chuàng)建 VM 時(shí) HYP 把一個(gè)特定的 GPA(KVM 中通過(guò)ioctl設(shè)置該地址)映射到 GICV base 物理地址,然后把這個(gè) GPA 作為 GICC base 在 device tree 中傳給 VM
VM 以為自己在訪問(wèn) GICC,實(shí)際上它在訪問(wèn) GICV
目前理解這些 GICV 寄存器在 vCPU switch 的時(shí)候是不需要保存的(KVM 里沒(méi)有保存 GICV 相關(guān)的代碼),因?yàn)樗鋵?shí)在硬件里訪問(wèn)的是 GICH 配置的那些寄存器,比如 LR
Virtual distributor (GICD in VM's view)
實(shí)際是內(nèi)核里的一個(gè)結(jié)構(gòu)體(struct vgic_dist)
在 device tree 中給 VM 一個(gè) GICD base,但實(shí)際上沒(méi)有映射
VM 訪問(wèn) GICD 時(shí),trap & emulate,直接返回或設(shè)置struct vgic_dist里的字段(在vgic-v2-emul.c文件中)
每個(gè) VM 一個(gè),而不是每個(gè) vCPU 一個(gè),所以struct vgic_dist放在struct kvm_arch里
VM's view
從 device tree 獲得 GICD、GICC base 物理地址(實(shí)際是 HYP 偽造的地址)
配置 GICD 寄存器(實(shí)際上 trap 到 HYP,模擬地讀寫了內(nèi)核某 struct 里的數(shù)據(jù))
執(zhí)行直到發(fā)生中斷(中斷先到 HYP,HYP 在 LR 中配置了一個(gè)物理 IRQ 到 vIRQ 的映射,并且設(shè)置為 pending,回到 VM 之后 GIC 在 VM 的 EL1 觸發(fā)中斷)
讀 GICC_IAR(經(jīng)過(guò) stage 2 頁(yè)表翻譯,實(shí)際上讀了 GICV_IAR,GIC 根據(jù) LR 返回 vIRQ 的信息,vIRQ 狀態(tài)從 pending 轉(zhuǎn)為 active)
寫 GICC_EOIR、GICC_DIR(經(jīng)過(guò) stage 2 頁(yè)表翻譯,實(shí)際上寫了 GICV_EOIR、GICV_DIR,GIC EOI 并 deactivate 對(duì)應(yīng)的 vIRQ,并 deactivate vIRQ 對(duì)應(yīng)的物理 IRQ)
GICv3
新特性:
CPU interface(GICC、GICH、GICV)通過(guò) system register 訪問(wèn)(ICC_*_ELn、ICH_*_EL2、ICV_*_ELn,ICC 和 ICV 在指令中的編碼相同,硬件根據(jù)當(dāng)前 EL 和 HCR_EL2 來(lái)路由),不再用 MMIO
使用 affinity routing,支持最多 2^32 個(gè) CPU 核心
引入 redistributor,每個(gè) CPU 一個(gè),和各 CPU interface 連接,使 PPI 不再需要進(jìn)入 distributor
引入一種新的中斷類型 LPI 和一個(gè)新的組件 ITS(還沒(méi)太看懂是干啥用的)
Non-virtualization
Virtualization
【作者】張昺華
【出處】http://www.cnblogs.com/sky-heaven/
【博客園】 http://www.cnblogs.com/sky-heaven/
【知乎】 http://www.zhihu.com/people/zhang-bing-hua
【我的作品---旋轉(zhuǎn)倒立擺】 http://v.youku.com/v_show/id_XODM5NDAzNjQw.html?spm=a2hzp.8253869.0.0&from=y1.7-2
【我的作品---自平衡自動(dòng)循跡車】 http://v.youku.com/v_show/id_XODM5MzYyNTIw.html?spm=a2hzp.8253869.0.0&from=y1.7-2
【大餅教你學(xué)系列】https://edu.csdn.net/course/detail/10393
【新浪微博】 張昺華--sky
【twitter】 @sky2030_
【微信公眾號(hào)】 張昺華
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利.
總結(jié)
以上是生活随笔為你收集整理的ARM GIC 虚拟化学习笔记【转】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ACM10.14题解
- 下一篇: edge浏览器清理缓存快捷键