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