From a65a347f34aea8333f1ba0c4ab04ef0d5c28085a Mon Sep 17 00:00:00 2001 From: Yuanyuan Zhao Date: Mon, 9 May 2022 09:18:35 +0800 Subject: [PATCH] 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 Reviewed-by: Junjie Mao --- hypervisor/dm/vrtc.c | 7 +++++++ hypervisor/include/dm/vrtc.h | 1 + 2 files changed, 8 insertions(+) diff --git a/hypervisor/dm/vrtc.c b/hypervisor/dm/vrtc.c index e43ecb799..e90163d1f 100644 --- a/hypervisor/dm/vrtc.c +++ b/hypervisor/dm/vrtc.c @@ -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); } diff --git a/hypervisor/include/dm/vrtc.h b/hypervisor/include/dm/vrtc.h index b760ce445..fa57eb542 100644 --- a/hypervisor/include/dm/vrtc.h +++ b/hypervisor/include/dm/vrtc.h @@ -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 */