ARM定义了通用计时器框架
通用定时器提供了一个计数器,其可以用来测量系统运行的时间
定时器还可被编程,是其在到达一定的时间后会想CPU发出一个时钟中断。
系统会经常访问该通用计数器.读取计数器和编程计时器是许多操作系统中用于进程调度和定期轮询设备状态的常见操作。
Linux读取计数器以确定进程的时间片是否已过期,并编写计时器以确保进程不超过其允许的时间片。
应用程序工作负载也经常使用计时器。
计时器可被hypervisor和guest操作系统使用
但是为了对计时器提供隔离并保留控制权,hypervisor使用的计时器不能直接被guest操作系统配置和操作。
如果guest操作系统需要访问此类计时器,则需要让CPU陷入到HYP模式来实现,对于某些工作负载相对频繁的操作则会产生额外的开销。
hypervisor也可能希望虚拟化虚拟机的时钟,因为让虚拟机直接访问计时器硬件将是是问题。
一次访问就要陷入一次 hypervisor , 这是不可忍受的
ARM 决定将 这个次数(1次) 优化成0次
ARM通过引入一个新的计数器来实现虚拟化支持,这时就有两个计数器 (虚拟计时器和物理计时器)
实际运行时
将hypervisor配置为使用物理计时器
将虚拟机配置成使用虚拟计时器。
对通用计时器的访问情况
从guest内核态访问物理计时器和计数器是由HYP模式控制的,要陷入 hyp mode
在guest内核模式下运行的软件总是可以访问虚拟计时器和虚拟计数器。
其他问题
访问虚拟计时器和虚拟计数器不会陷入 hyp mode
但是中断来了还是要陷入 hyp mode,且 ACK和EIO操作要在hyp 做
不幸的是,由于体系架构的限制,虚拟计时器不能直接引发虚拟中断,而总是死会引发硬件中断,这就会使CPU陷入hypervisor。
KVM/ARM检测虚拟机的虚拟计时器何时到期,并向虚拟机注入相应的虚拟中断,并在highvisor中执行所有的硬件ACK和EIO操作。
计数器个数限制
硬件仅为每个物理CPU提供一个虚拟计时器,多个虚拟CPU可以跨这个硬件实例进行多路复用。
为了在此场景中支持虚拟计时器
KVM/ARM在虚拟机捕获到hypervisor时检测未过期的计时器
并利用现有的操作系统功能,在虚拟机计时器启动时编写一个软件计时器。
当这样一个软件计时器触发时,将执行一个回调函数,该函数使用上面描述的虚拟分发服务器想虚拟机发出一个虚拟计时器中断