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:
Yuanyuan Zhao 2022-05-09 09:18:35 +08:00 committed by acrnsi-robot
parent 145a56d448
commit a65a347f34
2 changed files with 8 additions and 0 deletions

View File

@ -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);
}

View File

@ -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 */