zoukankan      html  css  js  c++  java
  • ARM GIC 虚拟化学习笔记【转】

    转自:https://stdrc.cc/post/2020/09/26/arm-gic-virtualization/

    这是一篇学习过程中的笔记,因为时间原因不再组织成流畅的语言,而是直接分享了~

    References

    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_*_ELnICH_*_EL2ICV_*_ELn,ICC 和 ICV 在指令中的编码相同,硬件根据当前 EL 和 HCR_EL2 来路由),不再用 MMIO
    • 使用 affinity routing,支持最多 2^32 个 CPU 核心
    • 引入 redistributor,每个 CPU 一个,和各 CPU interface 连接,使 PPI 不再需要进入 distributor
    • 引入一种新的中断类型 LPI 和一个新的组件 ITS(还没太看懂是干啥用的)

    Non-virtualization

    Virtualization

    【作者】张昺华
    【大饼教你学系列】https://edu.csdn.net/course/detail/10393
    【新浪微博】 张昺华--sky
    【twitter】 @sky2030_
    【微信公众号】 张昺华
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    百度地图常用 获取中心点 缩放级别等
    sqlserver 临时表,多用户同时访问冲突吗?
    批量改ID 行形式
    C# post Json数据
    windows 激活venv问题
    spring 改变url
    conductor编译镜像
    springboot教程
    Microsoft Visual C++ Compiler for Python 2.7
    java 方法引用(method reference)
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/15160567.html
Copyright © 2011-2022 走看看