>On 25/07/2017 06:14, peng.h...@zte.com.cn wrote:
>>> On 24/07/2017 20:35, Peng Hao wrote: >> >> >> >> >> >>>> When a windows vm starts, periodic timer of rtc will stop several times. >>>> windows kernel will check whether REG_A_UIP is changed. REG_C's interrupt >>>> flags will not be cleared when periodic timer stops and the update timer >>>> will switch to alarm timer. So the expiration time of alarm timer is very >>>> long and REG_A_UIP will not vary.At last windows kernel will repeat to >>>> check REG_A_UIP all the time. >> >>> This should not happen. REG_A_UIP is set and cleared in register A >>> every second, like this: >>> case RTC_REG_A: >>> if (update_in_progress(s)) { >>> s->cmos_data[s->cmos_index] |= REG_A_UIP >>> } else { >>> s->cmos_data[s->cmos_index] &= ~REG_A_UIP >>> } >>> ret = s->cmos_data[s->cmos_index] >>> break >> >> >> >> when periodic timer stop, update timer is set to a long expire time (as >> alarm timer). >I think I see the bug now: >diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c >index 1b8d3d7d4c..6184b4378e 100644 >--- a/hw/timer/mc146818rtc.c >+++ b/hw/timer/mc146818rtc.c >@@ -321,9 +321,11 @@ static void check_update_timer(RTCState *s) > s->next_alarm_time = next_update_time + > (next_alarm_sec - 1) * NANOSECONDS_PER_SECOND > >- if (s->cmos_data[RTC_REG_C] & REG_C_UF) { >- /* UF is set, but AF is clear. Program the timer to target >- * the alarm time. */ >+ if ((s->cmos_data[RTC_REG_C] & REG_C_UF) && >+ !(s->cmos_data[RTC_REG_A] & REG_A_UIP)) { >+ /* If UIP was latched, we need to clear it at the next update. >+ * Otherwise, if UF is set we only need to program the timer to >+ * target the alarm time. */ > next_update_time = s->next_alarm_time > } > if (next_update_time != timer_expire_time_ns(s->update_timer)) { >but I would like to have a testcase for it in tests/rtc-test.c. >Can you check if the above works and try writing a testcase (that fails >without the patch and succeeds with it)? >Thanks, I don't think it can works. REG_C_UF is totally cleared by periodic timer in original code. after periodic timer stoped, the REG_C_UF is never cleared. rtc_update_timer has cleared REG_A_UIP,I think the patch does nothing. I reproduce the bug when many windows VMs reboot and it is about the method of windows kernel accessing rtc . so i don't know how to write the testcase. >Paolo