ARMv7 KVM 在 linux中的实现 4 中断角度

我们在 该文章 中分析了 PL2 的异常,提出了以下问题

	什么虚拟化相关的情况下会进入 host_PL1
		TODO
	什么虚拟化相关的情况下会进入 host_PL2
		1. 虚拟机开启时,ioctl KVM_RUN 进入 hyp_hvc
		2. 中断应该会进入 hyp_irq 
		3. 内存异常应该会进入 hyp_dabt // TODO
	什么虚拟化相关的情况下会进入 guest_PL1
		1. 优化后的中断应该会进入 vector_irq // TODO
		2. 优化后的内存访问异常应该会进入 vector_dabt // TODO
————————————————
版权声明:本文为CSDN博主「__pop_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011011827/article/details/120470296


现在有了答案:
	guest间的核间中断,外设(都是qemu和kvm仿真的)的中断发生时,会进行如下动作
	1. 进入 host_PL2 hyp_irq 
	2. host_PL2 hyp_irq 中 分发服务器开始动作(对应的 CPU的GIC hypervisor控制接口上的列表寄存器(list register)进行编程)
	3. 进入 guest_PL1 vector_irq 
	4. guest_PL1 vector_irq 中 做 中断处理程序
	5. guest_PL1 vector_irq 中 确认 ACK和EOI
	6. 进入 guest 正常运行时

本篇文章着重从 irq 角度 分析 , 会牵涉到 host_PL2 的 hyp_irq 和 guest_PL1 的 vector_irq

  • 实体机上的 GIC
ARM 有一个 GIC

GIC的作用
	将中断从设备转发到CPU上,CPU通过查询GIC来探测该中断的来源。
	用于生成处理器间中断(IPI)从一个CPU核到另一个CPU核。
GIC分为
	分发服务器
		一个系统只有一个
		通过内存映射接口(MMIO)来进行访问的
		被用来配置GIC,例如,配置中断的CPU核与一个中断进行关联,禁止或者使能系统中的所有中断,发送IPI到另外一个CPU核。
	CPU接口
		一个cpu对应一个
		通过内存映射接口(MMIO)来进行访问的
		用于确认(ACK)和发出中断接口信号(EOI)。


CPU 对 中断的处理流程 : 当一个CPU核接收到一个中断时
	CPU:
		将读取GIC的CPU接口上的一个特殊寄存器,该寄存器将标记中断,并返回中断数量。
	GIC:
		在CPU将从ACK寄存器中读取到的值写入CPU接口的EOI寄存器之前,中断不会再次被转发到CPU中。
  • ARM 针对中断虚拟化的探讨
// 中断方案的探讨
中断可被配置为使CPU核陷入HOST的HYP模式(PL2)或者guest的svc模式(PL1) // 注意 : PL2也有svc
	guest_PL1
		将所有中断捕获到内核模式中,并让其被在内核模式下运行的操作系统软件直接处理是很高效的,
		但是其不能再虚拟机上下文中工作,因为hypervisor失去对硬件的控制
	host_PL2
		将所有中断捕获到HYP模式可确保hypervisor保留控制权,但是需要在软件中模拟虚拟中断,以便向虚拟机发出事件信号。
		这种方式就很麻烦且开销很大,因为处理中断的每一步和虚拟中断的处理,例如ACK和EOI操作都必须通过hypervisor来完成。
		开销
			1. 进入 host_PL2 的 hyp_irq
			2. host_PL2 的 hyp_irq : 分发服务器 将 陷入 guest_PL1 的 vector_irq
			3. guest_PL1 的 vector_irq:做处理
			4. guest_PL1 的 vector_irq :进入 host_PL2的hyp_irq , 做 ACK和EOI
			5. host_PL2的hyp_irq : 返回 guest_PL1 的 vector_irq
			6. guest_PL1 的 vector_irq : 返回 guest_PLx 的 正常运行时

现有问题:
	必须满足 : 让 host_PL2 参与 中断, 且 开销要 相比现在的方案开销(现在是一次中断,两次host_PL2进入)要 降低
解决方案:
	VGIC(一次中断,一次host_PL2进入)
  • ARM 针对虚拟化对 GIC的扩展 VGIC

VGIC方案 : GIC v2.0 以虚拟化GCI(VGIC)的形式提供了中断硬件虚拟化的支持
	不需要 在 hypervisor软件中进行 模拟来 创建 虚拟中断(而是直接写寄存器)
	不需要 再次陷入 hypervisor 做 ACK和EOI(而是直接在guest_PL1直接做)

VGIC分为
	分发服务器
		一个系统只有一个,由软件模拟
		虚拟机对分发服务器的所有访问仍然必须捕获到hypervisor中
		被用来配置GIC,例如,配置中断的CPU核与一个中断进行关联,禁止或者使能系统中的所有中断,发送IPI到另外一个CPU核。
	CPU接口
		一个cpu对应一个,由硬件实现
		通过 CPU的GIC hypervisor控制接口上的列表寄存器 来进行访问的,访问时不会陷入 hypervisor
		用于确认(ACK)和发出中断接口信号(EOI)

VGIC的处理方式
	1. 进入 host_PL2 的 hyp_irq
	2. host_PL2 的 hyp_irq : 分发服务器 将 陷入 guest_PL1 的 vector_irq // 这里通过 VGIC hypervisor控制接口中写入特殊寄存器(list registers) 加速
	3. guest_PL1 的 vector_irq:做处理
	4. guest_PL1 的 vector_irq :  做 ACK和EOI // 这里直接在 guest_PL1 的 vector_irq 做 ACK 和 EOI 加速
	5. guest_PL1 的 vector_irq : 返回 guest_PLx 的 正常运行时


CPU 对 中断的处理流程,当一个虚拟CPU发送了一个虚拟IPI到另外一个虚拟CPU
	CPU:
		1.陷入host的PL2 hypervisor
		2.模拟软件中的分发服务器访问并对接收到的CPU的GIC hypervisor控制接口上的列表寄存器(list register)进行编程
		3.陷入guest 的 guest_PL1
		4.在guest_PL1让guest操作系统 确认 ACK和EOI

CPU 对 中断的处理流程,当一个CPU核接收到一个中断时 // 模拟虚拟设备通常通过软阿健API将虚拟中断引入到hypervisor
	CPU:
		1. 陷入 host的 hypervisor
		2. 在host_PL2 利用 虚拟中断VGIC将模拟设备的虚拟中断号写入到列表寄存器(list register)中。
		3. 陷入guest 的 的内核模式
		4. 在guest_PL1让guest操作系统 确认 ACK和EOI


VGIC 其他细节
	虚拟分发服务器
		会向用户空间暴露一个接口 // 因此用户空间中的模拟设备可以向虚拟分发服务器发出虚拟中断
		并向虚拟机暴露一个与物理GIC分发服务器相同的MMIO接口。
	是否切换
		当将一个虚拟机调度到一个物理核上运行时,必须切换list寄存器的上下文
		但是在虚拟机和hypervisor之间进行切换时,List寄存器的上下文则不需切换。
		一旦系统hypervisor在切换到虚拟机时向list寄存器写入了虚拟中断,那么当切换回hypervisor时,它也必须重新读取list寄存器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值