debuggers.hg
changeset 17986: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>
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 /*