ia64/xen-unstable

changeset 17951:f2148e532c81

x86 hvm: Fix RTC handling.
1. Clean up initialisation/destruction.
2. Better handle per-domain time-offset changes.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Jul 02 17:25:05 2008 +0100 (2008-07-02)
parents 3a40a6997cc0
children 97b4c5c511f0
files xen/arch/ia64/xen/fw_emul.c xen/arch/x86/domain.c xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/rtc.c xen/arch/x86/time.c xen/common/domctl.c xen/include/asm-x86/hvm/vpt.h xen/include/xen/time.h
line diff
     1.1 --- a/xen/arch/ia64/xen/fw_emul.c	Wed Jul 02 17:10:52 2008 +0100
     1.2 +++ b/xen/arch/ia64/xen/fw_emul.c	Wed Jul 02 17:25:05 2008 +0100
     1.3 @@ -1061,6 +1061,11 @@ errout:
     1.4  	return status;
     1.5  }
     1.6  
     1.7 +void domain_set_time_offset(struct domain *d, int32_t time_offset_seconds)
     1.8 +{
     1.9 +	d->time_offset_seconds = time_offset_seconds;
    1.10 +}
    1.11 +
    1.12  static efi_status_t
    1.13  efi_emulate_set_time(
    1.14  	unsigned long tv_addr, IA64FAULT *fault)
     2.1 --- a/xen/arch/x86/domain.c	Wed Jul 02 17:10:52 2008 +0100
     2.2 +++ b/xen/arch/x86/domain.c	Wed Jul 02 17:25:05 2008 +0100
     2.3 @@ -452,6 +452,7 @@ int arch_domain_create(struct domain *d,
     2.4      return 0;
     2.5  
     2.6   fail:
     2.7 +    d->is_dying = DOMDYING_dead;
     2.8      free_xenheap_page(d->shared_info);
     2.9      if ( paging_initialised )
    2.10          paging_final_teardown(d);
     3.1 --- a/xen/arch/x86/hvm/hvm.c	Wed Jul 02 17:10:52 2008 +0100
     3.2 +++ b/xen/arch/x86/hvm/hvm.c	Wed Jul 02 17:25:05 2008 +0100
     3.3 @@ -314,6 +314,8 @@ int hvm_domain_initialise(struct domain 
     3.4  
     3.5      stdvga_init(d);
     3.6  
     3.7 +    rtc_init(d);
     3.8 +
     3.9      hvm_init_ioreq_page(d, &d->arch.hvm_domain.ioreq);
    3.10      hvm_init_ioreq_page(d, &d->arch.hvm_domain.buf_ioreq);
    3.11  
    3.12 @@ -326,6 +328,8 @@ int hvm_domain_initialise(struct domain 
    3.13      return 0;
    3.14  
    3.15   fail2:
    3.16 +    rtc_deinit(d);
    3.17 +    stdvga_deinit(d);
    3.18      vioapic_deinit(d);
    3.19   fail1:
    3.20      hvm_destroy_cacheattr_region_list(d);
    3.21 @@ -337,16 +341,21 @@ void hvm_domain_relinquish_resources(str
    3.22      hvm_destroy_ioreq_page(d, &d->arch.hvm_domain.ioreq);
    3.23      hvm_destroy_ioreq_page(d, &d->arch.hvm_domain.buf_ioreq);
    3.24  
    3.25 -    pit_deinit(d);
    3.26 +    /* Stop all asynchronous timer actions. */
    3.27      rtc_deinit(d);
    3.28 -    pmtimer_deinit(d);
    3.29 -    hpet_deinit(d);
    3.30 -    stdvga_deinit(d);
    3.31 +    if ( d->vcpu[0] != NULL )
    3.32 +    {
    3.33 +        pit_deinit(d);
    3.34 +        pmtimer_deinit(d);
    3.35 +        hpet_deinit(d);
    3.36 +    }
    3.37  }
    3.38  
    3.39  void hvm_domain_destroy(struct domain *d)
    3.40  {
    3.41      hvm_funcs.domain_destroy(d);
    3.42 +    rtc_deinit(d);
    3.43 +    stdvga_deinit(d);
    3.44      vioapic_deinit(d);
    3.45      hvm_destroy_cacheattr_region_list(d);
    3.46  }
    3.47 @@ -658,7 +667,6 @@ int hvm_vcpu_initialise(struct vcpu *v)
    3.48      {
    3.49          /* NB. All these really belong in hvm_domain_initialise(). */
    3.50          pit_init(v, cpu_khz);
    3.51 -        rtc_init(v, RTC_PORT(0));
    3.52          pmtimer_init(v);
    3.53          hpet_init(v);
    3.54   
    3.55 @@ -2131,7 +2139,7 @@ static void hvm_s3_suspend(struct domain
    3.56      domain_pause(d);
    3.57      domain_lock(d);
    3.58  
    3.59 -    if ( (d->vcpu[0] == NULL) ||
    3.60 +    if ( d->is_dying || (d->vcpu[0] == NULL) ||
    3.61           test_and_set_bool(d->arch.hvm_domain.is_s3_suspended) )
    3.62      {
    3.63          domain_unlock(d);
     4.1 --- a/xen/arch/x86/hvm/rtc.c	Wed Jul 02 17:10:52 2008 +0100
     4.2 +++ b/xen/arch/x86/hvm/rtc.c	Wed Jul 02 17:25:05 2008 +0100
     4.3 @@ -186,16 +186,9 @@ static void rtc_set_time(RTCState *s)
     4.4  static void rtc_copy_date(RTCState *s)
     4.5  {
     4.6      const struct tm *tm = &s->current_tm;
     4.7 -    struct domain *d = vrtc_domain(s);
     4.8  
     4.9      ASSERT(spin_is_locked(&s->lock));
    4.10  
    4.11 -    if ( s->time_offset_seconds != d->time_offset_seconds )
    4.12 -    {
    4.13 -        s->current_tm = gmtime(get_localtime(d));
    4.14 -        s->time_offset_seconds = d->time_offset_seconds;
    4.15 -    }
    4.16 -
    4.17      s->hw.cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec);
    4.18      s->hw.cmos_data[RTC_MINUTES] = to_bcd(s, tm->tm_min);
    4.19      if ( s->hw.cmos_data[RTC_REG_B] & RTC_24H )
    4.20 @@ -237,16 +230,9 @@ static void rtc_next_second(RTCState *s)
    4.21  {
    4.22      struct tm *tm = &s->current_tm;
    4.23      int days_in_month;
    4.24 -    struct domain *d = vrtc_domain(s);
    4.25  
    4.26      ASSERT(spin_is_locked(&s->lock));
    4.27  
    4.28 -    if ( s->time_offset_seconds != d->time_offset_seconds )
    4.29 -    {
    4.30 -        s->current_tm = gmtime(get_localtime(d));
    4.31 -        s->time_offset_seconds = d->time_offset_seconds;
    4.32 -    }
    4.33 -
    4.34      tm->tm_sec++;
    4.35      if ( (unsigned)tm->tm_sec >= 60 )
    4.36      {
    4.37 @@ -474,46 +460,61 @@ static int rtc_load(struct domain *d, hv
    4.38  
    4.39  HVM_REGISTER_SAVE_RESTORE(RTC, rtc_save, rtc_load, 1, HVMSR_PER_DOM);
    4.40  
    4.41 +void rtc_reset(struct domain *d)
    4.42 +{
    4.43 +    RTCState *s = domain_vrtc(d);
    4.44  
    4.45 -void rtc_init(struct vcpu *v, int base)
    4.46 +    destroy_periodic_time(&s->pt);
    4.47 +    s->pt.source = PTSRC_isa;
    4.48 +}
    4.49 +
    4.50 +void rtc_init(struct domain *d)
    4.51  {
    4.52 -    RTCState *s = vcpu_vrtc(v);
    4.53 +    RTCState *s = domain_vrtc(d);
    4.54  
    4.55      spin_lock_init(&s->lock);
    4.56  
    4.57 -    s->pt.source = PTSRC_isa;
    4.58 +    init_timer(&s->second_timer, rtc_update_second, s, smp_processor_id());
    4.59 +    init_timer(&s->second_timer2, rtc_update_second2, s, smp_processor_id());
    4.60 +
    4.61 +    register_portio_handler(d, RTC_PORT(0), 2, handle_rtc_io);
    4.62 +
    4.63 +    rtc_reset(d);
    4.64 +
    4.65 +    spin_lock(&s->lock);
    4.66  
    4.67      s->hw.cmos_data[RTC_REG_A] = RTC_REF_CLCK_32KHZ | 6; /* ~1kHz */
    4.68      s->hw.cmos_data[RTC_REG_B] = RTC_24H;
    4.69      s->hw.cmos_data[RTC_REG_C] = 0;
    4.70      s->hw.cmos_data[RTC_REG_D] = RTC_VRT;
    4.71  
    4.72 -    s->current_tm = gmtime(get_localtime(v->domain));
    4.73 +    s->current_tm = gmtime(get_localtime(d));
    4.74  
    4.75 -    spin_lock(&s->lock);
    4.76      rtc_copy_date(s);
    4.77 -    spin_unlock(&s->lock);
    4.78 -
    4.79 -    init_timer(&s->second_timer, rtc_update_second, s, v->processor);
    4.80 -    init_timer(&s->second_timer2, rtc_update_second2, s, v->processor);
    4.81  
    4.82      s->next_second_time = NOW() + 1000000000ULL;
    4.83 +    stop_timer(&s->second_timer);
    4.84      set_timer(&s->second_timer2, s->next_second_time);
    4.85  
    4.86 -    register_portio_handler(v->domain, base, 2, handle_rtc_io);
    4.87 +    spin_unlock(&s->lock);
    4.88  }
    4.89  
    4.90  void rtc_deinit(struct domain *d)
    4.91  {
    4.92      RTCState *s = domain_vrtc(d);
    4.93  
    4.94 +    spin_barrier(&s->lock);
    4.95 +
    4.96      destroy_periodic_time(&s->pt);
    4.97      kill_timer(&s->second_timer);
    4.98      kill_timer(&s->second_timer2);
    4.99  }
   4.100  
   4.101 -void rtc_reset(struct domain *d)
   4.102 +void rtc_update_clock(struct domain *d)
   4.103  {
   4.104      RTCState *s = domain_vrtc(d);
   4.105 -    destroy_periodic_time(&s->pt);
   4.106 +
   4.107 +    spin_lock(&s->lock);
   4.108 +    s->current_tm = gmtime(get_localtime(d));
   4.109 +    spin_unlock(&s->lock);
   4.110  }
     5.1 --- a/xen/arch/x86/time.c	Wed Jul 02 17:10:52 2008 +0100
     5.2 +++ b/xen/arch/x86/time.c	Wed Jul 02 17:25:05 2008 +0100
     5.3 @@ -745,6 +745,13 @@ void update_domain_wallclock_time(struct
     5.4      spin_unlock(&wc_lock);
     5.5  }
     5.6  
     5.7 +void domain_set_time_offset(struct domain *d, int32_t time_offset_seconds)
     5.8 +{
     5.9 +    d->time_offset_seconds = time_offset_seconds;
    5.10 +    if ( is_hvm_domain(d) )
    5.11 +        rtc_update_clock(d);
    5.12 +}
    5.13 +
    5.14  int cpu_frequency_change(u64 freq)
    5.15  {
    5.16      struct cpu_time *t = &this_cpu(cpu_time);
     6.1 --- a/xen/common/domctl.c	Wed Jul 02 17:10:52 2008 +0100
     6.2 +++ b/xen/common/domctl.c	Wed Jul 02 17:25:05 2008 +0100
     6.3 @@ -787,7 +787,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
     6.4              break;
     6.5          }
     6.6  
     6.7 -        d->time_offset_seconds = op->u.settimeoffset.time_offset_seconds;
     6.8 +        domain_set_time_offset(d, op->u.settimeoffset.time_offset_seconds);
     6.9          rcu_unlock_domain(d);
    6.10          ret = 0;
    6.11      }
     7.1 --- a/xen/include/asm-x86/hvm/vpt.h	Wed Jul 02 17:10:52 2008 +0100
     7.2 +++ b/xen/include/asm-x86/hvm/vpt.h	Wed Jul 02 17:25:05 2008 +0100
     7.3 @@ -118,7 +118,6 @@ typedef struct RTCState {
     7.4      struct timer second_timer;
     7.5      struct timer second_timer2;
     7.6      struct periodic_time pt;
     7.7 -    int32_t time_offset_seconds;
     7.8      spinlock_t lock;
     7.9  } RTCState;
    7.10  
    7.11 @@ -176,10 +175,11 @@ void pit_reset(struct domain *d);
    7.12  void pit_init(struct vcpu *v, unsigned long cpu_khz);
    7.13  void pit_stop_channel0_irq(PITState * pit);
    7.14  void pit_deinit(struct domain *d);
    7.15 -void rtc_init(struct vcpu *v, int base);
    7.16 +void rtc_init(struct domain *d);
    7.17  void rtc_migrate_timers(struct vcpu *v);
    7.18  void rtc_deinit(struct domain *d);
    7.19  void rtc_reset(struct domain *d);
    7.20 +void rtc_update_clock(struct domain *d);
    7.21  
    7.22  void pmtimer_init(struct vcpu *v);
    7.23  void pmtimer_deinit(struct domain *d);
     8.1 --- a/xen/include/xen/time.h	Wed Jul 02 17:10:52 2008 +0100
     8.2 +++ b/xen/include/xen/time.h	Wed Jul 02 17:25:05 2008 +0100
     8.3 @@ -61,6 +61,8 @@ extern void do_settime(
     8.4  
     8.5  extern void send_timer_event(struct vcpu *v);
     8.6  
     8.7 +void domain_set_time_offset(struct domain *d, int32_t time_offset_seconds);
     8.8 +
     8.9  #endif /* __XEN_TIME_H__ */
    8.10  
    8.11  /*