[PATCH v5 8/8] hv: calibrate vrtc when modify physical time


Zhao, Yuanyuan
 

For Service VM modify physical rtc time and vrtc will calibrate
time by read physical rtc. So when Service VM modify physical
time, calibrate all vrtc.

Reviewed-by: Junjie Mao <junjie.mao@...>
Signed-off-by: Yuanyuan Zhao <yuanyuan.zhao@...>
---
hypervisor/dm/vrtc.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/hypervisor/dm/vrtc.c b/hypervisor/dm/vrtc.c
index 2231e31ca..e27fe0909 100644
--- a/hypervisor/dm/vrtc.c
+++ b/hypervisor/dm/vrtc.c
@@ -41,6 +41,9 @@
#endif
# define RTC_ERR pr_err

+static time_t vrtc_get_physical_rtc_time(struct acrn_vrtc *vrtc);
+static void vrtc_update_basetime(time_t physical_time, time_t offset);
+
struct clktime {
uint32_t year; /* year (4 digit year) */
uint32_t mon; /* month (1 - 12) */
@@ -524,6 +527,12 @@ static bool vrtc_read(struct acrn_vcpu *vcpu, uint16_t addr, __unused size_t wid
return ret;
}

+static inline bool vrtc_is_time_register(uint32_t offset)
+{
+ return (offset == RTC_SEC || offset == RTC_MIN || offset == RTC_HRS || offset == RTC_DAY
+ || offset == RTC_MONTH || offset == RTC_YEAR || offset == RTC_CENTURY);
+}
+
/**
* @pre vcpu != NULL
* @pre vcpu->vm != NULL
@@ -533,12 +542,22 @@ static bool vrtc_write(struct acrn_vcpu *vcpu, uint16_t addr, size_t width,
{
time_t current, after;
struct acrn_vrtc *vrtc = &vcpu->vm->vrtc;
+ struct acrn_vrtc temp_vrtc;
+ bool is_time_register;

if ((width == 1U) && (addr == CMOS_ADDR_PORT)) {
vrtc->addr = (uint8_t)(value & 0x7FU);
} else {
if (is_service_vm(vcpu->vm)) {
- cmos_set_reg_val(vrtc->addr, (uint8_t)(value & 0xFFU));
+ is_time_register = vrtc_is_time_register(vrtc->addr);
+ if (is_time_register) {
+ current = vrtc_get_physical_rtc_time(&temp_vrtc);
+ }
+ cmos_set_reg_val(vcpu->vm->vrtc.addr, (uint8_t)(value & 0xFFU));
+ if (is_time_register) {
+ after = vrtc_get_physical_rtc_time(&temp_vrtc);
+ vrtc_update_basetime(after, current - after);
+ }
} else {
switch (vrtc->addr) {
case RTC_STATUSA:
--
2.25.1