[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |