[PATCH v4 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.

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 ee9b47087..1b27be99f 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


Junjie Mao
 

Yuanyuan Zhao <yuanyuan.zhao@...> writes:

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.

Signed-off-by: Yuanyuan Zhao <yuanyuan.zhao@...>
Reviewed-by: Junjie Mao <junjie.mao@...>

---
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 ee9b47087..1b27be99f 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:
--
Best Regards
Junjie Mao