本文将介绍kvm中lapic timer的虚拟化。为了方便,只介绍TSC-deadline模式的lapic timer
本文参考的内核版本为v5.18

host有自己的lapic timer,硬件实现,guest也有自己的lapic timer,kvm模拟。一个pcup上要运行很多个vcpu,每个vcpu都有自己的lapic timer,kvm要模拟很多个lapic timer,kvm用软件定时器hrtimer来模拟lapic timer,guest写tscdeadline msr,kvm把这个tsc值转换成一个软件定时器的值,启动软件定时器,硬件定时器驱动软件定时器,软件定时器超时后,假如硬件timer中断正好把vcpu exiting出来,那么设置timer interrupt pending,重新enter时把timer中断注入,如果vcpu运行在其它pcpu上,需要把vcpu kick出来,所以最好保持timer绑定的物理cpu和vcpu所运行的物理cpu始终一致,如果vcpu运行的物理cpu变化了,migrate timer到新的物理cpu,这样中断来了vcpu自动exit,不再需要kick一次。

hrtimer由physical lapic timer来驱动。

1
2
3
4
5
kvm_set_lapic_tscdeadline_msr
└── start_apic_timer
└── __start_apic_timer
└── restart_apic_timer
└── if (!start_hv_timer(apic)) start_sw_timer(apic);

这里的hv_timer就是preemption timer,sw_timer是软件hrtimer。有preemption timer就用hv_timer,没有就用sw_timer。hv_timer的问题就是可能时间没到,vcpu由于其它原因exit出来,那么就需要kvm_lapic_switch_to_sw_timer,再次enter时kvm_lapic_switch_to_hv_timer。

1
2
3
4
start_hv_timer
├── vmx_set_hv_timer[kvm_x86_set_hv_timer]
├── ktimer->hv_timer_in_use = true;
└── hrtimer_cancel(&ktimer->timer);
1
2
3
start_sw_timer
└── start_sw_tscdeadline
└── hrtimer_start

参考资料:

  1. kvm timer虚拟化
  2. APIC Timer模拟