On 25/07/2017 11:29, peng.h...@zte.com.cn wrote: >>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.
Have you tested it? > REG_C_UF is totally cleared by periodic timer in original code. > after periodic timer stoped, the REG_C_UF is never cleared. Your patch cleared REG_C_UF, but you have not said why the actual hardware would clear REG_C_UF (it wouldn't). > 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. First of all you have to describe the exact sequence of register accesses that causes the problem. I can help you writing the testcase, but your changes to the device model must reflect the actual behavior of the hardware. Paolo