ia64/xen-unstable

changeset 15364:ba61ec7df632

hvm: Simplify timer<->vcpu/domain conversion in RTC and PIT timer
models. These timers are always bound to vcpu0, where a specific vcpu
matters.
Signed-off-by: Keir Fraser <keir@xensource.com>
author Keir Fraser <keir@xensource.com>
date Fri Jun 15 10:36:31 2007 +0100 (2007-06-15)
parents 9a915873be8c
children f1ba2e652724
files xen/arch/x86/hvm/i8254.c xen/arch/x86/hvm/rtc.c
line diff
     1.1 --- a/xen/arch/x86/hvm/i8254.c	Fri Jun 15 10:01:32 2007 +0100
     1.2 +++ b/xen/arch/x86/hvm/i8254.c	Fri Jun 15 10:36:31 2007 +0100
     1.3 @@ -37,6 +37,12 @@
     1.4  #include <asm/hvm/vpt.h>
     1.5  #include <asm/current.h>
     1.6  
     1.7 +#define domain_vpit(d)   (&(d)->arch.hvm_domain.pl_time.vpit)
     1.8 +#define vcpu_vpit(vcpu)  (domain_vpit((vcpu)->domain))
     1.9 +#define vpit_domain(pit) (container_of((pit), struct domain, \
    1.10 +                                       arch.hvm_domain.pl_time.vpit))
    1.11 +#define vpit_vcpu(pit)   (vpit_domain(pit)->vcpu[0])
    1.12 +
    1.13  #define RW_STATE_LSB 1
    1.14  #define RW_STATE_MSB 2
    1.15  #define RW_STATE_WORD0 3
    1.16 @@ -45,8 +51,8 @@
    1.17  static int handle_pit_io(ioreq_t *p);
    1.18  static int handle_speaker_io(ioreq_t *p);
    1.19  
    1.20 -/* compute with 96 bit intermediate result: (a*b)/c */
    1.21 -uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
    1.22 +/* Compute with 96 bit intermediate result: (a*b)/c */
    1.23 +static uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
    1.24  {
    1.25      union {
    1.26          uint64_t ll;
    1.27 @@ -69,15 +75,16 @@ uint64_t muldiv64(uint64_t a, uint32_t b
    1.28      return res.ll;
    1.29  }
    1.30  
    1.31 -static int pit_get_count(PITState *s, int channel)
    1.32 +static int pit_get_count(PITState *pit, int channel)
    1.33  {
    1.34      uint64_t d;
    1.35      int  counter;
    1.36 -    struct hvm_hw_pit_channel *c = &s->hw.channels[channel];
    1.37 -    struct periodic_time *pt = &s->pt[channel];
    1.38 +    struct hvm_hw_pit_channel *c = &pit->hw.channels[channel];
    1.39 +    struct vcpu *v = vpit_vcpu(pit);
    1.40  
    1.41 -    d = muldiv64(hvm_get_guest_time(pt->vcpu) - s->count_load_time[channel],
    1.42 -                 PIT_FREQ, ticks_per_sec(pt->vcpu));
    1.43 +    d = muldiv64(hvm_get_guest_time(v) - pit->count_load_time[channel],
    1.44 +                 PIT_FREQ, ticks_per_sec(v));
    1.45 +
    1.46      switch ( c->mode )
    1.47      {
    1.48      case 0:
    1.49 @@ -97,15 +104,15 @@ static int pit_get_count(PITState *s, in
    1.50      return counter;
    1.51  }
    1.52  
    1.53 -int pit_get_out(PITState *pit, int channel)
    1.54 +static int pit_get_out(PITState *pit, int channel)
    1.55  {
    1.56      struct hvm_hw_pit_channel *s = &pit->hw.channels[channel];
    1.57 -    uint64_t d, current_time;
    1.58 +    uint64_t d;
    1.59      int out;
    1.60 +    struct vcpu *v = vpit_vcpu(pit);
    1.61  
    1.62 -    current_time = hvm_get_guest_time(pit->pt[channel].vcpu);
    1.63 -    d = muldiv64(current_time - pit->count_load_time[channel], 
    1.64 -                 PIT_FREQ, ticks_per_sec(pit->pt[channel].vcpu));
    1.65 +    d = muldiv64(hvm_get_guest_time(v) - pit->count_load_time[channel], 
    1.66 +                 PIT_FREQ, ticks_per_sec(v));
    1.67  
    1.68      switch ( s->mode )
    1.69      {
    1.70 @@ -131,11 +138,10 @@ int pit_get_out(PITState *pit, int chann
    1.71      return out;
    1.72  }
    1.73  
    1.74 -/* val must be 0 or 1 */
    1.75 -void pit_set_gate(PITState *pit, int channel, int val)
    1.76 +static void pit_set_gate(PITState *pit, int channel, int val)
    1.77  {
    1.78      struct hvm_hw_pit_channel *s = &pit->hw.channels[channel];
    1.79 -    struct periodic_time *pt = &pit->pt[channel];
    1.80 +    struct vcpu *v = vpit_vcpu(pit);
    1.81  
    1.82      switch ( s->mode )
    1.83      {
    1.84 @@ -150,7 +156,7 @@ void pit_set_gate(PITState *pit, int cha
    1.85      case 3:
    1.86          /* Restart counting on rising edge. */
    1.87          if ( s->gate < val )
    1.88 -            pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu);
    1.89 +            pit->count_load_time[channel] = hvm_get_guest_time(v);
    1.90          break;
    1.91      }
    1.92  
    1.93 @@ -162,7 +168,7 @@ int pit_get_gate(PITState *pit, int chan
    1.94      return pit->hw.channels[channel].gate;
    1.95  }
    1.96  
    1.97 -void pit_time_fired(struct vcpu *v, void *priv)
    1.98 +static void pit_time_fired(struct vcpu *v, void *priv)
    1.99  {
   1.100      uint64_t *count_load_time = priv;
   1.101      *count_load_time = hvm_get_guest_time(v);
   1.102 @@ -173,9 +179,7 @@ static void pit_load_count(PITState *pit
   1.103      u32 period;
   1.104      struct hvm_hw_pit_channel *s = &pit->hw.channels[channel];
   1.105      struct periodic_time *pt = &pit->pt[channel];
   1.106 -    struct domain *d = container_of(pit, struct domain,
   1.107 -                                    arch.hvm_domain.pl_time.vpit);
   1.108 -    struct vcpu *v;
   1.109 +    struct vcpu *v = vpit_vcpu(pit);
   1.110  
   1.111      if ( val == 0 )
   1.112          val = 0x10000;
   1.113 @@ -184,15 +188,9 @@ static void pit_load_count(PITState *pit
   1.114      s->count = val;
   1.115      period = DIV_ROUND((val * 1000000000ULL), PIT_FREQ);
   1.116  
   1.117 -    if ( !is_hvm_domain(d) || (channel != 0) )
   1.118 +    if ( (v == NULL) || !is_hvm_vcpu(v) || (channel != 0) )
   1.119          return;
   1.120  
   1.121 -    /* Choose a vcpu to set the timer on: current if appropriate else vcpu 0 */
   1.122 -    if ( pit == &current->domain->arch.hvm_domain.pl_time.vpit )
   1.123 -        v = current;
   1.124 -    else 
   1.125 -        v = d->vcpu[0];
   1.126 -
   1.127      switch ( s->mode )
   1.128      {
   1.129          case 2:
   1.130 @@ -235,9 +233,8 @@ static void pit_latch_status(PITState *s
   1.131      }
   1.132  }
   1.133  
   1.134 -static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val)
   1.135 +static void pit_ioport_write(struct PITState *pit, uint32_t addr, uint32_t val)
   1.136  {
   1.137 -    PITState *pit = opaque;
   1.138      int channel, access;
   1.139      struct hvm_hw_pit_channel *s;
   1.140  
   1.141 @@ -309,9 +306,8 @@ static void pit_ioport_write(void *opaqu
   1.142      }
   1.143  }
   1.144  
   1.145 -static uint32_t pit_ioport_read(void *opaque, uint32_t addr)
   1.146 +static uint32_t pit_ioport_read(struct PITState *pit, uint32_t addr)
   1.147  {
   1.148 -    PITState *pit = opaque;
   1.149      int ret, count;
   1.150      struct hvm_hw_pit_channel *s;
   1.151      
   1.152 @@ -371,7 +367,7 @@ static uint32_t pit_ioport_read(void *op
   1.153      return ret;
   1.154  }
   1.155  
   1.156 -void pit_stop_channel0_irq(PITState * pit)
   1.157 +void pit_stop_channel0_irq(PITState *pit)
   1.158  {
   1.159      destroy_periodic_time(&pit->pt[0]);
   1.160  }
   1.161 @@ -425,7 +421,7 @@ static void pit_info(PITState *pit)
   1.162  
   1.163  static int pit_save(struct domain *d, hvm_domain_context_t *h)
   1.164  {
   1.165 -    PITState *pit = &d->arch.hvm_domain.pl_time.vpit;
   1.166 +    PITState *pit = domain_vpit(d);
   1.167      
   1.168      pit_info(pit);
   1.169  
   1.170 @@ -435,7 +431,7 @@ static int pit_save(struct domain *d, hv
   1.171  
   1.172  static int pit_load(struct domain *d, hvm_domain_context_t *h)
   1.173  {
   1.174 -    PITState *pit = &d->arch.hvm_domain.pl_time.vpit;
   1.175 +    PITState *pit = domain_vpit(d);
   1.176      int i;
   1.177  
   1.178      /* Restore the PIT hardware state */
   1.179 @@ -457,27 +453,13 @@ static int pit_load(struct domain *d, hv
   1.180  
   1.181  HVM_REGISTER_SAVE_RESTORE(PIT, pit_save, pit_load, 1, HVMSR_PER_DOM);
   1.182  
   1.183 -static void pit_reset(void *opaque)
   1.184 +void pit_init(struct vcpu *v, unsigned long cpu_khz)
   1.185  {
   1.186 -    PITState *pit = opaque;
   1.187 +    PITState *pit = vcpu_vpit(v);
   1.188 +    struct periodic_time *pt;
   1.189      struct hvm_hw_pit_channel *s;
   1.190      int i;
   1.191  
   1.192 -    for ( i = 0; i < 3; i++ )
   1.193 -    {
   1.194 -        s = &pit->hw.channels[i];
   1.195 -        destroy_periodic_time(&pit->pt[i]);
   1.196 -        s->mode = 0xff; /* the init mode */
   1.197 -        s->gate = (i != 2);
   1.198 -        pit_load_count(pit, i, 0);
   1.199 -    }
   1.200 -}
   1.201 -
   1.202 -void pit_init(struct vcpu *v, unsigned long cpu_khz)
   1.203 -{
   1.204 -    PITState *pit = &v->domain->arch.hvm_domain.pl_time.vpit;
   1.205 -    struct periodic_time *pt;
   1.206 -
   1.207      pt = &pit->pt[0];  
   1.208      pt[0].vcpu = v;
   1.209      pt[1].vcpu = v;
   1.210 @@ -487,20 +469,26 @@ void pit_init(struct vcpu *v, unsigned l
   1.211      /* register the speaker port */
   1.212      register_portio_handler(v->domain, 0x61, 1, handle_speaker_io);
   1.213      ticks_per_sec(v) = cpu_khz * (int64_t)1000;
   1.214 -    pit_reset(pit);
   1.215 +
   1.216 +    for ( i = 0; i < 3; i++ )
   1.217 +    {
   1.218 +        s = &pit->hw.channels[i];
   1.219 +        s->mode = 0xff; /* the init mode */
   1.220 +        s->gate = (i != 2);
   1.221 +        pit_load_count(pit, i, 0);
   1.222 +    }
   1.223  }
   1.224  
   1.225  void pit_deinit(struct domain *d)
   1.226  {
   1.227 -    PITState *pit = &d->arch.hvm_domain.pl_time.vpit;
   1.228 +    PITState *pit = domain_vpit(d);
   1.229      destroy_periodic_time(&pit->pt[0]);
   1.230  }
   1.231  
   1.232  /* the intercept action for PIT DM retval:0--not handled; 1--handled */  
   1.233  static int handle_pit_io(ioreq_t *p)
   1.234  {
   1.235 -    struct vcpu *v = current;
   1.236 -    struct PITState *vpit = &(v->domain->arch.hvm_domain.pl_time.vpit);
   1.237 +    struct PITState *vpit = vcpu_vpit(current);
   1.238  
   1.239      if ( (p->size != 1) || p->data_is_ptr || (p->type != IOREQ_TYPE_PIO) )
   1.240      {
   1.241 @@ -523,16 +511,16 @@ static int handle_pit_io(ioreq_t *p)
   1.242      return 1;
   1.243  }
   1.244  
   1.245 -static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val)
   1.246 +static void speaker_ioport_write(
   1.247 +    struct PITState *pit, uint32_t addr, uint32_t val)
   1.248  {
   1.249 -    PITState *pit = opaque;
   1.250      pit->hw.speaker_data_on = (val >> 1) & 1;
   1.251      pit_set_gate(pit, 2, val & 1);
   1.252  }
   1.253  
   1.254 -static uint32_t speaker_ioport_read(void *opaque, uint32_t addr)
   1.255 +static uint32_t speaker_ioport_read(
   1.256 +    struct PITState *pit, uint32_t addr)
   1.257  {
   1.258 -    PITState *pit = opaque;
   1.259      /* Refresh clock toggles at about 15us. We approximate as 2^14ns. */
   1.260      unsigned int refresh_clock = ((unsigned int)NOW() >> 14) & 1;
   1.261      return ((pit->hw.speaker_data_on << 1) | pit_get_gate(pit, 2) |
   1.262 @@ -541,8 +529,7 @@ static uint32_t speaker_ioport_read(void
   1.263  
   1.264  static int handle_speaker_io(ioreq_t *p)
   1.265  {
   1.266 -    struct vcpu *v = current;
   1.267 -    struct PITState *vpit = &(v->domain->arch.hvm_domain.pl_time.vpit);
   1.268 +    struct PITState *vpit = vcpu_vpit(current);
   1.269  
   1.270      if ( (p->size != 1) || p->data_is_ptr || (p->type != IOREQ_TYPE_PIO) )
   1.271      {
     2.1 --- a/xen/arch/x86/hvm/rtc.c	Fri Jun 15 10:01:32 2007 +0100
     2.2 +++ b/xen/arch/x86/hvm/rtc.c	Fri Jun 15 10:36:31 2007 +0100
     2.3 @@ -28,6 +28,12 @@
     2.4  #include <asm/hvm/support.h>
     2.5  #include <asm/current.h>
     2.6  
     2.7 +#define domain_vrtc(d)   (&(d)->arch.hvm_domain.pl_time.vrtc)
     2.8 +#define vcpu_vrtc(vcpu)  (domain_vrtc((vcpu)->domain))
     2.9 +#define vrtc_domain(rtc) (container_of((rtc), struct domain, \
    2.10 +                                       arch.hvm_domain.pl_time.vrtc))
    2.11 +#define vrtc_vcpu(rtc)   (vrtc_domain(rtc)->vcpu[0])
    2.12 +
    2.13  void rtc_periodic_cb(struct vcpu *v, void *opaque)
    2.14  {
    2.15      RTCState *s = opaque;
    2.16 @@ -39,15 +45,15 @@ int is_rtc_periodic_irq(void *opaque)
    2.17      RTCState *s = opaque;
    2.18  
    2.19      return !(s->hw.cmos_data[RTC_REG_C] & RTC_AF || 
    2.20 -           s->hw.cmos_data[RTC_REG_C] & RTC_UF);
    2.21 +             s->hw.cmos_data[RTC_REG_C] & RTC_UF);
    2.22  }
    2.23  
    2.24  /* Enable/configure/disable the periodic timer based on the RTC_PIE and
    2.25   * RTC_RATE_SELECT settings */
    2.26 -static void rtc_timer_update(RTCState *s, struct vcpu *v)
    2.27 +static void rtc_timer_update(RTCState *s)
    2.28  {
    2.29 -    int period_code; 
    2.30 -    int period;
    2.31 +    int period_code, period;
    2.32 +    struct vcpu *v = vrtc_vcpu(s);
    2.33  
    2.34      period_code = s->hw.cmos_data[RTC_REG_A] & RTC_RATE_SELECT;
    2.35      if ( (period_code != 0) && (s->hw.cmos_data[RTC_REG_B] & RTC_PIE) )
    2.36 @@ -104,7 +110,7 @@ static int rtc_ioport_write(void *opaque
    2.37          /* UIP bit is read only */
    2.38          s->hw.cmos_data[RTC_REG_A] = (data & ~RTC_UIP) |
    2.39              (s->hw.cmos_data[RTC_REG_A] & RTC_UIP);
    2.40 -        rtc_timer_update(s, current);
    2.41 +        rtc_timer_update(s);
    2.42          break;
    2.43      case RTC_REG_B:
    2.44          if ( data & RTC_SET )
    2.45 @@ -120,7 +126,7 @@ static int rtc_ioport_write(void *opaque
    2.46                  rtc_set_time(s);
    2.47          }
    2.48          s->hw.cmos_data[RTC_REG_B] = data;
    2.49 -        rtc_timer_update(s, current);
    2.50 +        rtc_timer_update(s);
    2.51          break;
    2.52      case RTC_REG_C:
    2.53      case RTC_REG_D:
    2.54 @@ -174,11 +180,12 @@ static void rtc_set_time(RTCState *s)
    2.55  static void rtc_copy_date(RTCState *s)
    2.56  {
    2.57      const struct tm *tm = &s->current_tm;
    2.58 +    struct domain *d = vrtc_domain(s);
    2.59  
    2.60 -    if ( s->time_offset_seconds != s->pt.vcpu->domain->time_offset_seconds )
    2.61 +    if ( s->time_offset_seconds != d->time_offset_seconds )
    2.62      {
    2.63 -        s->current_tm = gmtime(get_localtime(s->pt.vcpu->domain));
    2.64 -        s->time_offset_seconds = s->pt.vcpu->domain->time_offset_seconds;
    2.65 +        s->current_tm = gmtime(get_localtime(d));
    2.66 +        s->time_offset_seconds = d->time_offset_seconds;
    2.67      }
    2.68  
    2.69      s->hw.cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec);
    2.70 @@ -222,11 +229,12 @@ static void rtc_next_second(RTCState *s)
    2.71  {
    2.72      struct tm *tm = &s->current_tm;
    2.73      int days_in_month;
    2.74 +    struct domain *d = vrtc_domain(s);
    2.75  
    2.76 -    if ( s->time_offset_seconds != s->pt.vcpu->domain->time_offset_seconds )
    2.77 +    if ( s->time_offset_seconds != d->time_offset_seconds )
    2.78      {
    2.79 -        s->current_tm = gmtime(get_localtime(s->pt.vcpu->domain));
    2.80 -        s->time_offset_seconds = s->pt.vcpu->domain->time_offset_seconds;
    2.81 +        s->current_tm = gmtime(get_localtime(d));
    2.82 +        s->time_offset_seconds = d->time_offset_seconds;
    2.83      }
    2.84  
    2.85      tm->tm_sec++;
    2.86 @@ -292,6 +300,7 @@ static void rtc_update_second(void *opaq
    2.87  static void rtc_update_second2(void *opaque)
    2.88  {
    2.89      RTCState *s = opaque;
    2.90 +    struct domain *d = vrtc_domain(s);
    2.91  
    2.92      if ( !(s->hw.cmos_data[RTC_REG_B] & RTC_SET) )
    2.93          rtc_copy_date(s);
    2.94 @@ -310,8 +319,8 @@ static void rtc_update_second2(void *opa
    2.95                s->current_tm.tm_hour) )
    2.96          {
    2.97              s->hw.cmos_data[RTC_REG_C] |= 0xa0; 
    2.98 -            hvm_isa_irq_deassert(s->pt.vcpu->domain, RTC_IRQ);
    2.99 -            hvm_isa_irq_assert(s->pt.vcpu->domain, RTC_IRQ);
   2.100 +            hvm_isa_irq_deassert(d, RTC_IRQ);
   2.101 +            hvm_isa_irq_assert(d, RTC_IRQ);
   2.102          }
   2.103      }
   2.104  
   2.105 @@ -319,8 +328,8 @@ static void rtc_update_second2(void *opa
   2.106      if ( s->hw.cmos_data[RTC_REG_B] & RTC_UIE )
   2.107      {
   2.108          s->hw.cmos_data[RTC_REG_C] |= 0x90; 
   2.109 -        hvm_isa_irq_deassert(s->pt.vcpu->domain, RTC_IRQ);
   2.110 -        hvm_isa_irq_assert(s->pt.vcpu->domain, RTC_IRQ);
   2.111 +        hvm_isa_irq_deassert(d, RTC_IRQ);
   2.112 +        hvm_isa_irq_assert(d, RTC_IRQ);
   2.113      }
   2.114  
   2.115      /* clear update in progress bit */
   2.116 @@ -354,8 +363,8 @@ static uint32_t rtc_ioport_read(void *op
   2.117          break;
   2.118      case RTC_REG_C:
   2.119          ret = s->hw.cmos_data[s->hw.cmos_index];
   2.120 -        hvm_isa_irq_deassert(s->pt.vcpu->domain, RTC_IRQ);
   2.121 -        s->hw.cmos_data[RTC_REG_C] = 0x00; 
   2.122 +        hvm_isa_irq_deassert(vrtc_domain(s), RTC_IRQ);
   2.123 +        s->hw.cmos_data[RTC_REG_C] = 0x00;
   2.124          break;
   2.125      default:
   2.126          ret = s->hw.cmos_data[s->hw.cmos_index];
   2.127 @@ -367,8 +376,7 @@ static uint32_t rtc_ioport_read(void *op
   2.128  
   2.129  static int handle_rtc_io(ioreq_t *p)
   2.130  {
   2.131 -    struct vcpu *v = current;
   2.132 -    struct RTCState *vrtc = &v->domain->arch.hvm_domain.pl_time.vrtc;
   2.133 +    struct RTCState *vrtc = vcpu_vrtc(current);
   2.134  
   2.135      if ( (p->size != 1) || p->data_is_ptr || (p->type != IOREQ_TYPE_PIO) )
   2.136      {
   2.137 @@ -392,7 +400,7 @@ static int handle_rtc_io(ioreq_t *p)
   2.138  
   2.139  void rtc_migrate_timers(struct vcpu *v)
   2.140  {
   2.141 -    RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc;
   2.142 +    RTCState *s = vcpu_vrtc(v);
   2.143  
   2.144      if ( v->vcpu_id == 0 )
   2.145      {
   2.146 @@ -404,13 +412,14 @@ void rtc_migrate_timers(struct vcpu *v)
   2.147  /* Save RTC hardware state */
   2.148  static int rtc_save(struct domain *d, hvm_domain_context_t *h)
   2.149  {
   2.150 -    return hvm_save_entry(RTC, 0, h, &d->arch.hvm_domain.pl_time.vrtc.hw);
   2.151 +    RTCState *s = domain_vrtc(d);
   2.152 +    return hvm_save_entry(RTC, 0, h, &s->hw);
   2.153  }
   2.154  
   2.155  /* Reload the hardware state from a saved domain */
   2.156  static int rtc_load(struct domain *d, hvm_domain_context_t *h)
   2.157  {
   2.158 -    RTCState *s = &d->arch.hvm_domain.pl_time.vrtc;    
   2.159 +    RTCState *s = domain_vrtc(d);
   2.160  
   2.161      /* Restore the registers */
   2.162      if ( hvm_load_entry(RTC, h, &s->hw) != 0 )
   2.163 @@ -425,7 +434,7 @@ static int rtc_load(struct domain *d, hv
   2.164      set_timer(&s->second_timer2, s->next_second_time);
   2.165  
   2.166      /* Reset the periodic interrupt timer based on the registers */
   2.167 -    rtc_timer_update(s, d->vcpu[0]);
   2.168 +    rtc_timer_update(s);
   2.169  
   2.170      return 0;
   2.171  }
   2.172 @@ -435,9 +444,8 @@ HVM_REGISTER_SAVE_RESTORE(RTC, rtc_save,
   2.173  
   2.174  void rtc_init(struct vcpu *v, int base)
   2.175  {
   2.176 -    RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc;
   2.177 +    RTCState *s = vcpu_vrtc(v);
   2.178  
   2.179 -    s->pt.vcpu = v;
   2.180      s->hw.cmos_data[RTC_REG_A] = RTC_REF_CLCK_32KHZ | 6; /* ~1kHz */
   2.181      s->hw.cmos_data[RTC_REG_B] = RTC_24H;
   2.182      s->hw.cmos_data[RTC_REG_C] = 0;
   2.183 @@ -457,7 +465,7 @@ void rtc_init(struct vcpu *v, int base)
   2.184  
   2.185  void rtc_deinit(struct domain *d)
   2.186  {
   2.187 -    RTCState *s = &d->arch.hvm_domain.pl_time.vrtc;
   2.188 +    RTCState *s = domain_vrtc(d);
   2.189  
   2.190      destroy_periodic_time(&s->pt);
   2.191      kill_timer(&s->second_timer);