[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86 hvm: Fix RTC handling.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1215015905 -3600
# Node ID f2148e532c81b7591eb67e6880a08e60d8a9ff7e
# Parent  3a40a6997cc0610a17136fd38da1d0a1f94d932b
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@xxxxxxxxxx>
---
 xen/arch/ia64/xen/fw_emul.c   |    5 +++
 xen/arch/x86/domain.c         |    1 
 xen/arch/x86/hvm/hvm.c        |   28 +++++++++++-------
 xen/arch/x86/hvm/rtc.c        |   65 +++++++++++++++++++++---------------------
 xen/arch/x86/time.c           |    7 ++++
 xen/common/domctl.c           |    2 -
 xen/include/asm-x86/hvm/vpt.h |    4 +-
 xen/include/xen/time.h        |    2 +
 8 files changed, 69 insertions(+), 45 deletions(-)

diff -r 3a40a6997cc0 -r f2148e532c81 xen/arch/ia64/xen/fw_emul.c
--- a/xen/arch/ia64/xen/fw_emul.c       Wed Jul 02 17:10:52 2008 +0100
+++ b/xen/arch/ia64/xen/fw_emul.c       Wed Jul 02 17:25:05 2008 +0100
@@ -1061,6 +1061,11 @@ errout:
        return status;
 }
 
+void domain_set_time_offset(struct domain *d, int32_t time_offset_seconds)
+{
+       d->time_offset_seconds = time_offset_seconds;
+}
+
 static efi_status_t
 efi_emulate_set_time(
        unsigned long tv_addr, IA64FAULT *fault)
diff -r 3a40a6997cc0 -r f2148e532c81 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Wed Jul 02 17:10:52 2008 +0100
+++ b/xen/arch/x86/domain.c     Wed Jul 02 17:25:05 2008 +0100
@@ -452,6 +452,7 @@ int arch_domain_create(struct domain *d,
     return 0;
 
  fail:
+    d->is_dying = DOMDYING_dead;
     free_xenheap_page(d->shared_info);
     if ( paging_initialised )
         paging_final_teardown(d);
diff -r 3a40a6997cc0 -r f2148e532c81 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Wed Jul 02 17:10:52 2008 +0100
+++ b/xen/arch/x86/hvm/hvm.c    Wed Jul 02 17:25:05 2008 +0100
@@ -314,6 +314,8 @@ int hvm_domain_initialise(struct domain 
 
     stdvga_init(d);
 
+    rtc_init(d);
+
     hvm_init_ioreq_page(d, &d->arch.hvm_domain.ioreq);
     hvm_init_ioreq_page(d, &d->arch.hvm_domain.buf_ioreq);
 
@@ -326,6 +328,8 @@ int hvm_domain_initialise(struct domain 
     return 0;
 
  fail2:
+    rtc_deinit(d);
+    stdvga_deinit(d);
     vioapic_deinit(d);
  fail1:
     hvm_destroy_cacheattr_region_list(d);
@@ -337,16 +341,21 @@ void hvm_domain_relinquish_resources(str
     hvm_destroy_ioreq_page(d, &d->arch.hvm_domain.ioreq);
     hvm_destroy_ioreq_page(d, &d->arch.hvm_domain.buf_ioreq);
 
-    pit_deinit(d);
+    /* Stop all asynchronous timer actions. */
     rtc_deinit(d);
-    pmtimer_deinit(d);
-    hpet_deinit(d);
+    if ( d->vcpu[0] != NULL )
+    {
+        pit_deinit(d);
+        pmtimer_deinit(d);
+        hpet_deinit(d);
+    }
+}
+
+void hvm_domain_destroy(struct domain *d)
+{
+    hvm_funcs.domain_destroy(d);
+    rtc_deinit(d);
     stdvga_deinit(d);
-}
-
-void hvm_domain_destroy(struct domain *d)
-{
-    hvm_funcs.domain_destroy(d);
     vioapic_deinit(d);
     hvm_destroy_cacheattr_region_list(d);
 }
@@ -658,7 +667,6 @@ int hvm_vcpu_initialise(struct vcpu *v)
     {
         /* NB. All these really belong in hvm_domain_initialise(). */
         pit_init(v, cpu_khz);
-        rtc_init(v, RTC_PORT(0));
         pmtimer_init(v);
         hpet_init(v);
  
@@ -2131,7 +2139,7 @@ static void hvm_s3_suspend(struct domain
     domain_pause(d);
     domain_lock(d);
 
-    if ( (d->vcpu[0] == NULL) ||
+    if ( d->is_dying || (d->vcpu[0] == NULL) ||
          test_and_set_bool(d->arch.hvm_domain.is_s3_suspended) )
     {
         domain_unlock(d);
diff -r 3a40a6997cc0 -r f2148e532c81 xen/arch/x86/hvm/rtc.c
--- a/xen/arch/x86/hvm/rtc.c    Wed Jul 02 17:10:52 2008 +0100
+++ b/xen/arch/x86/hvm/rtc.c    Wed Jul 02 17:25:05 2008 +0100
@@ -186,15 +186,8 @@ static void rtc_copy_date(RTCState *s)
 static void rtc_copy_date(RTCState *s)
 {
     const struct tm *tm = &s->current_tm;
-    struct domain *d = vrtc_domain(s);
 
     ASSERT(spin_is_locked(&s->lock));
-
-    if ( s->time_offset_seconds != d->time_offset_seconds )
-    {
-        s->current_tm = gmtime(get_localtime(d));
-        s->time_offset_seconds = d->time_offset_seconds;
-    }
 
     s->hw.cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec);
     s->hw.cmos_data[RTC_MINUTES] = to_bcd(s, tm->tm_min);
@@ -237,15 +230,8 @@ static void rtc_next_second(RTCState *s)
 {
     struct tm *tm = &s->current_tm;
     int days_in_month;
-    struct domain *d = vrtc_domain(s);
 
     ASSERT(spin_is_locked(&s->lock));
-
-    if ( s->time_offset_seconds != d->time_offset_seconds )
-    {
-        s->current_tm = gmtime(get_localtime(d));
-        s->time_offset_seconds = d->time_offset_seconds;
-    }
 
     tm->tm_sec++;
     if ( (unsigned)tm->tm_sec >= 60 )
@@ -474,46 +460,61 @@ static int rtc_load(struct domain *d, hv
 
 HVM_REGISTER_SAVE_RESTORE(RTC, rtc_save, rtc_load, 1, HVMSR_PER_DOM);
 
-
-void rtc_init(struct vcpu *v, int base)
-{
-    RTCState *s = vcpu_vrtc(v);
+void rtc_reset(struct domain *d)
+{
+    RTCState *s = domain_vrtc(d);
+
+    destroy_periodic_time(&s->pt);
+    s->pt.source = PTSRC_isa;
+}
+
+void rtc_init(struct domain *d)
+{
+    RTCState *s = domain_vrtc(d);
 
     spin_lock_init(&s->lock);
 
-    s->pt.source = PTSRC_isa;
+    init_timer(&s->second_timer, rtc_update_second, s, smp_processor_id());
+    init_timer(&s->second_timer2, rtc_update_second2, s, smp_processor_id());
+
+    register_portio_handler(d, RTC_PORT(0), 2, handle_rtc_io);
+
+    rtc_reset(d);
+
+    spin_lock(&s->lock);
 
     s->hw.cmos_data[RTC_REG_A] = RTC_REF_CLCK_32KHZ | 6; /* ~1kHz */
     s->hw.cmos_data[RTC_REG_B] = RTC_24H;
     s->hw.cmos_data[RTC_REG_C] = 0;
     s->hw.cmos_data[RTC_REG_D] = RTC_VRT;
 
-    s->current_tm = gmtime(get_localtime(v->domain));
-
-    spin_lock(&s->lock);
+    s->current_tm = gmtime(get_localtime(d));
+
     rtc_copy_date(s);
-    spin_unlock(&s->lock);
-
-    init_timer(&s->second_timer, rtc_update_second, s, v->processor);
-    init_timer(&s->second_timer2, rtc_update_second2, s, v->processor);
 
     s->next_second_time = NOW() + 1000000000ULL;
+    stop_timer(&s->second_timer);
     set_timer(&s->second_timer2, s->next_second_time);
 
-    register_portio_handler(v->domain, base, 2, handle_rtc_io);
+    spin_unlock(&s->lock);
 }
 
 void rtc_deinit(struct domain *d)
 {
     RTCState *s = domain_vrtc(d);
+
+    spin_barrier(&s->lock);
 
     destroy_periodic_time(&s->pt);
     kill_timer(&s->second_timer);
     kill_timer(&s->second_timer2);
 }
 
-void rtc_reset(struct domain *d)
-{
-    RTCState *s = domain_vrtc(d);
-    destroy_periodic_time(&s->pt);
-}
+void rtc_update_clock(struct domain *d)
+{
+    RTCState *s = domain_vrtc(d);
+
+    spin_lock(&s->lock);
+    s->current_tm = gmtime(get_localtime(d));
+    spin_unlock(&s->lock);
+}
diff -r 3a40a6997cc0 -r f2148e532c81 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c       Wed Jul 02 17:10:52 2008 +0100
+++ b/xen/arch/x86/time.c       Wed Jul 02 17:25:05 2008 +0100
@@ -745,6 +745,13 @@ void update_domain_wallclock_time(struct
     spin_unlock(&wc_lock);
 }
 
+void domain_set_time_offset(struct domain *d, int32_t time_offset_seconds)
+{
+    d->time_offset_seconds = time_offset_seconds;
+    if ( is_hvm_domain(d) )
+        rtc_update_clock(d);
+}
+
 int cpu_frequency_change(u64 freq)
 {
     struct cpu_time *t = &this_cpu(cpu_time);
diff -r 3a40a6997cc0 -r f2148e532c81 xen/common/domctl.c
--- a/xen/common/domctl.c       Wed Jul 02 17:10:52 2008 +0100
+++ b/xen/common/domctl.c       Wed Jul 02 17:25:05 2008 +0100
@@ -787,7 +787,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
             break;
         }
 
-        d->time_offset_seconds = op->u.settimeoffset.time_offset_seconds;
+        domain_set_time_offset(d, op->u.settimeoffset.time_offset_seconds);
         rcu_unlock_domain(d);
         ret = 0;
     }
diff -r 3a40a6997cc0 -r f2148e532c81 xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h     Wed Jul 02 17:10:52 2008 +0100
+++ b/xen/include/asm-x86/hvm/vpt.h     Wed Jul 02 17:25:05 2008 +0100
@@ -118,7 +118,6 @@ typedef struct RTCState {
     struct timer second_timer;
     struct timer second_timer2;
     struct periodic_time pt;
-    int32_t time_offset_seconds;
     spinlock_t lock;
 } RTCState;
 
@@ -176,10 +175,11 @@ void pit_init(struct vcpu *v, unsigned l
 void pit_init(struct vcpu *v, unsigned long cpu_khz);
 void pit_stop_channel0_irq(PITState * pit);
 void pit_deinit(struct domain *d);
-void rtc_init(struct vcpu *v, int base);
+void rtc_init(struct domain *d);
 void rtc_migrate_timers(struct vcpu *v);
 void rtc_deinit(struct domain *d);
 void rtc_reset(struct domain *d);
+void rtc_update_clock(struct domain *d);
 
 void pmtimer_init(struct vcpu *v);
 void pmtimer_deinit(struct domain *d);
diff -r 3a40a6997cc0 -r f2148e532c81 xen/include/xen/time.h
--- a/xen/include/xen/time.h    Wed Jul 02 17:10:52 2008 +0100
+++ b/xen/include/xen/time.h    Wed Jul 02 17:25:05 2008 +0100
@@ -61,6 +61,8 @@ extern void do_settime(
 
 extern void send_timer_event(struct vcpu *v);
 
+void domain_set_time_offset(struct domain *d, int32_t time_offset_seconds);
+
 #endif /* __XEN_TIME_H__ */
 
 /*

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.