hv: vRTC monotonic growth
For physical RTC is monotonic growth, ensure vRTC monotonicity. Periodical calibration and physical RTC modification may have impact. Check it before reading Tracked-On: #7440 Signed-off-by: Yuanyuan Zhao <yuanyuan.zhao@linux.intel.com> Reviewed-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
parent
145a56d448
commit
a65a347f34
|
@ -386,6 +386,11 @@ static time_t vrtc_get_current_time(struct acrn_vrtc *vrtc)
|
|||
if (vrtc->base_rtctime > 0) {
|
||||
offset = (cpu_ticks() - vrtc->base_tsc) / (get_tsc_khz() * 1000U);
|
||||
second = vrtc->base_rtctime + vrtc->offset_rtctime + (time_t)offset;
|
||||
if (second < vrtc->last_rtctime) {
|
||||
second = vrtc->last_rtctime;
|
||||
} else {
|
||||
vrtc->last_rtctime = second;
|
||||
}
|
||||
}
|
||||
spinlock_release(&vrtc_rebase_lock);
|
||||
return second;
|
||||
|
@ -590,6 +595,7 @@ static bool vrtc_write(struct acrn_vcpu *vcpu, uint16_t addr, size_t width,
|
|||
after = rtc_to_secs(vrtc);
|
||||
spinlock_obtain(&vrtc_rebase_lock);
|
||||
vrtc->offset_rtctime += after - current;
|
||||
vrtc->last_rtctime = VRTC_BROKEN_TIME;
|
||||
spinlock_release(&vrtc_rebase_lock);
|
||||
break;
|
||||
}
|
||||
|
@ -682,6 +688,7 @@ static void vrtc_set_basetime(struct acrn_vrtc *vrtc)
|
|||
current = rtc_to_secs(vrtc);
|
||||
spinlock_obtain(&vrtc_rebase_lock);
|
||||
vrtc->base_rtctime = current;
|
||||
vrtc->last_rtctime = VRTC_BROKEN_TIME;
|
||||
spinlock_release(&vrtc_rebase_lock);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ struct acrn_vrtc {
|
|||
|
||||
time_t base_rtctime; /* Base time calulated from physical rtc register. */
|
||||
time_t offset_rtctime; /* RTC offset against base time. */
|
||||
time_t last_rtctime; /* Last RTC time, to keep monotonicity. */
|
||||
|
||||
uint64_t base_tsc; /* Base tsc value */
|
||||
|
||||
|
|
Loading…
Reference in New Issue