kvm虛擬化之時鐘虛擬化

 

(文章來自作者維護的社區微信公衆號【虛擬化雲計算】)
(目前有兩個微信羣《kvm虛擬化》和《openstack》,掃描二維碼點擊“雲-交流”,進羣交流提問)

    我們知道kvm有一個半虛擬化的時鐘kvm-clock,但是現在只對Linux Guest支持,半虛擬化的時鐘具有準確高效的有點,而使用TSC和RTC等時鐘存在效率低高延遲的缺點,本文具體介紹一下虛擬化下的時鐘原理。

 
傳統時鐘
      我們知道傳統時鐘有RTC/HPET/PIT/ACPI PM TIMER/TSC等, 這些時鐘按原理可分成兩類:提供中斷的週期性時鐘, 如RTC/PIT/HPET等;另一種是提供COUNTER計數器的單步遞增性時鐘,如TSC。
 
虛擬化下的時鐘
 
1.TSC
Guest中使用rdtsc指令讀取TSC時,會因爲EXIT_REASON_RDTSC導致VM Exit。VMM讀取Host的TSC和VMCS中的TSC_OFFSET,然後把host_tst+tsc_offset返回給Guest。
要做出OFFSET的原因是考慮到vcpu熱插拔和Guest會在不同的Host間遷移。
 
2.qemu軟件模擬的時鐘:
qemu中有對RTC和hpet都模擬出了相應的設備,例如RTC的典型芯片mc146818。
這種軟件模擬時鐘中斷存在的問題:由於qemu也是應用程序,收到cpu調度的影響,軟件時鐘中斷不能及時產生,並且軟件時鐘中斷注入則是每次發生VM Exit/Vm Entry的時刻。所以軟件模擬時鐘就無法精準的出發並注入到Guest,存在延遲較大的問題。
 
3.kvm-clock:
    kvm-clock是KVM下Linux Guest默認的半虛擬化時鐘源。在Guest上實現一個kvmclock驅動,Guest通過該驅動向VMM查詢時間。
   其工作流程也比較簡單:Guest分配一個內存頁,將該內存地址通過寫入MSR告訴VMM,VMM把Host系統時間寫入這個內存頁,然後Guest去讀取這個時間來更新。
  這裏使用到的兩個MSR是:MSR_KVM_WALL_CLOCK_NEW和MSR_KVM_SYSTEM_TIME_NEW(這是新的,使用cpuid 0x40000001來標誌使用新的還是舊的)分別對應pvclock_wall_clock和pvclock_vcpu_time_info(具體結構體中的內容在內核代碼中可查看)。
 
Linux Guest中查看當前時鐘源是否爲kvm-clock:
$ cat /sys/devices/system/clocksource/clocksource0/current_clocksource
kvm-clock
 
Windows Guest處理時間漂移問題:
摘一下qemu代碼中qemu-options.hx的原文:
(-rtc [base=utc|localtime|date][,clock=host|vm][,driftfix=none|slew])
Enable @option{driftfix} (i386 targets only) if you experience time drift problems, specifically with Windows' ACPI HAL. This option will try to figure out how many timer interrupts were not processed by the Windows guest and will re-inject them.
 
============================================================
關注微信公衆號【虛擬化雲計算】,閱讀更多虛擬化雲計算知識,純技術乾貨更新不停。

 

發佈了43 篇原創文章 · 獲贊 83 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章