WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [HVM] Decouple the RTC from the PIT perio

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [HVM] Decouple the RTC from the PIT periodic timer
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 16 Nov 2006 19:20:15 +0000
Delivery-date: Thu, 16 Nov 2006 11:20:00 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
# Node ID 5f7b5e5ca14b6c00d8ac23d1a2ece62fcbaebc03
# Parent  992723a0ceb1b5e474797ca2634a07d1ba3faff6
[HVM] Decouple the RTC from the PIT periodic timer
Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/hvm.c            |   17 +++++++
 xen/arch/x86/hvm/i8259.c          |   12 ----
 xen/arch/x86/hvm/rtc.c            |   92 +++++++++++++++++++++++++-------------
 xen/arch/x86/hvm/svm/svm.c        |   23 +--------
 xen/arch/x86/hvm/vioapic.c        |    4 -
 xen/arch/x86/hvm/vmx/vmcs.c       |    2 
 xen/arch/x86/hvm/vmx/vmx.c        |   22 ++-------
 xen/include/asm-x86/hvm/hvm.h     |    1 
 xen/include/asm-x86/hvm/vmx/vmx.h |    1 
 xen/include/asm-x86/hvm/vpt.h     |    8 ++-
 10 files changed, 97 insertions(+), 85 deletions(-)

diff -r 992723a0ceb1 -r 5f7b5e5ca14b xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Thu Nov 16 15:20:05 2006 +0000
+++ b/xen/arch/x86/hvm/hvm.c    Thu Nov 16 17:07:23 2006 +0000
@@ -74,6 +74,20 @@ void hvm_set_guest_time(struct vcpu *v, 
     hvm_funcs.set_tsc_offset(v, v->arch.hvm_vcpu.cache_tsc_offset);
 }
 
+void hvm_migrate_timers(struct vcpu *v)
+{
+    struct periodic_time *pt = &v->domain->arch.hvm_domain.pl_time.periodic_tm;
+    struct PMTState *vpmt = &v->domain->arch.hvm_domain.pl_time.vpmt;
+
+    if ( pt->enabled )
+    {
+        migrate_timer(&pt->timer, v->processor);
+    }
+    migrate_timer(&vcpu_vlapic(v)->vlapic_timer, v->processor);
+    migrate_timer(&vpmt->timer, v->processor);
+    rtc_migrate_timers(v);
+}
+
 void hvm_do_resume(struct vcpu *v)
 {
     ioreq_t *p;
@@ -91,6 +105,9 @@ void hvm_do_resume(struct vcpu *v)
         }
         pickup_deactive_ticks(pt);
     }
+
+    /* Re-enable the RTC timer if needed */
+    rtc_thaw(v);
 
     /* NB. Optimised for common case (p->state == STATE_IOREQ_NONE). */
     p = &get_vio(v->domain, v->vcpu_id)->vp_ioreq;
diff -r 992723a0ceb1 -r 5f7b5e5ca14b xen/arch/x86/hvm/i8259.c
--- a/xen/arch/x86/hvm/i8259.c  Thu Nov 16 15:20:05 2006 +0000
+++ b/xen/arch/x86/hvm/i8259.c  Thu Nov 16 17:07:23 2006 +0000
@@ -536,8 +536,6 @@ int is_periodic_irq(struct vcpu *v, int 
     int vec;
     struct periodic_time *pt =
         &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
-    struct RTCState *vrtc =
-        &(v->domain->arch.hvm_domain.pl_time.vrtc);
 
     if (pt->irq == 0) { /* Is it pit irq? */
         if (type == APIC_DM_EXTINT)
@@ -549,16 +547,6 @@ int is_periodic_irq(struct vcpu *v, int 
             return 1;
     }
 
-    if (pt->irq == 8) { /* Or rtc irq? */
-        if (type == APIC_DM_EXTINT)
-            vec = domain_vpic(v->domain)->pics[1].irq_base;
-        else
-            vec = domain_vioapic(v->domain)->redirtbl[8].fields.vector;
-
-        if (irq == vec)
-            return is_rtc_periodic_irq(vrtc);
-    }
-
     return 0;
 }
 
diff -r 992723a0ceb1 -r 5f7b5e5ca14b xen/arch/x86/hvm/rtc.c
--- a/xen/arch/x86/hvm/rtc.c    Thu Nov 16 15:20:05 2006 +0000
+++ b/xen/arch/x86/hvm/rtc.c    Thu Nov 16 17:07:23 2006 +0000
@@ -30,40 +30,43 @@
 
 /* #define DEBUG_RTC */
 
-void rtc_periodic_cb(struct vcpu *v, void *opaque)
-{
-    RTCState *s = opaque;
-    s->cmos_data[RTC_REG_C] |= 0xc0;
-}
-
-int is_rtc_periodic_irq(void *opaque)
-{
-    RTCState *s = opaque;
-    return !(s->cmos_data[RTC_REG_C] & RTC_AF || 
-           s->cmos_data[RTC_REG_C] & RTC_UF);
-}
-
-static void rtc_timer_update(RTCState *s, int64_t current_time)
+/* Callback that fires the RTC's periodic interrupt */
+void rtc_pie_callback(void *opaque)
+{
+    RTCState *s = opaque;
+    struct hvm_domain *plat = &s->vcpu->domain->arch.hvm_domain;
+    struct vpic       *pic  = &plat->vpic;
+    /* Record that we have fired */
+    s->cmos_data[RTC_REG_C] |= (RTC_IRQF|RTC_PF); /* 0xc0 */
+    /* Fire */
+    pic_set_irq(pic, s->irq, 1);
+    /* Remember to fire again */
+    s->next_pie = NOW() + s->period;
+    set_timer(&s->pie_timer, s->next_pie);
+}
+
+/* Enable/configure/disable the periodic timer based on the RTC_PIE and
+ * RTC_RATE_SELECT settings */
+static void rtc_timer_update(RTCState *s)
 {
     int period_code; 
     int period;
 
-    period_code = s->cmos_data[RTC_REG_A] & 0x0f;
+    period_code = s->cmos_data[RTC_REG_A] & RTC_RATE_SELECT;
     if (period_code != 0 && (s->cmos_data[RTC_REG_B] & RTC_PIE)) {
         if (period_code <= 2)
             period_code += 7;
         
         period = 1 << (period_code - 1); /* period in 32 Khz cycles */
         period = DIV_ROUND((period * 1000000000ULL), 32768); /* period in ns */
-
+        s->period = period;
 #ifdef DEBUG_RTC
         printk("HVM_RTC: period = %uns\n", period);
 #endif
-
-        s->pt = create_periodic_time(period, RTC_IRQ, 0, rtc_periodic_cb, s);
-    } else if (s->pt) {
-        destroy_periodic_time(s->pt);
-        s->pt = NULL;
+        s->next_pie = NOW() + s->period;
+        set_timer(&s->pie_timer, s->next_pie);
+    } else {
+        stop_timer(&s->pie_timer);
     }
 }
 
@@ -105,7 +108,7 @@ static int rtc_ioport_write(void *opaque
             /* UIP bit is read only */
             s->cmos_data[RTC_REG_A] = (data & ~RTC_UIP) |
                 (s->cmos_data[RTC_REG_A] & RTC_UIP);
-            rtc_timer_update(s, hvm_get_clock(s->vcpu));
+            rtc_timer_update(s);
             break;
         case RTC_REG_B:
             if (data & RTC_SET) {
@@ -119,14 +122,14 @@ static int rtc_ioport_write(void *opaque
                 }
             }
             s->cmos_data[RTC_REG_B] = data;
-            rtc_timer_update(s, hvm_get_clock(s->vcpu));
+            rtc_timer_update(s);
             break;
         case RTC_REG_C:
         case RTC_REG_D:
             /* cannot write to them */
             break;
+        }
         return 1;
-        }
     }
     return 0;
 }
@@ -172,7 +175,7 @@ static void rtc_copy_date(RTCState *s)
 
     s->cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec);
     s->cmos_data[RTC_MINUTES] = to_bcd(s, tm->tm_min);
-    if (s->cmos_data[RTC_REG_B] & 0x02) {
+    if (s->cmos_data[RTC_REG_B] & RTC_24H) {
         /* 24 hour format */
         s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour);
     } else {
@@ -245,7 +248,7 @@ static void rtc_update_second(void *opaq
     RTCState *s = opaque;
 
     /* if the oscillator is not in normal operation, we do not update */
-    if ((s->cmos_data[RTC_REG_A] & 0x70) != 0x20) {
+    if ((s->cmos_data[RTC_REG_A] & RTC_DIV_CTL) != RTC_REF_CLCK_32KHZ) {
         s->next_second_time += 1000000000ULL;
         set_timer(&s->second_timer, s->next_second_time);
     } else {
@@ -361,22 +364,48 @@ static int handle_rtc_io(ioreq_t *p)
     return 0;
 }
 
+/* Stop the periodic interrupts from this RTC */
+void rtc_freeze(struct vcpu *v)
+{
+    RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc;
+    stop_timer(&s->pie_timer);
+}
+
+/* Start them again */
+void rtc_thaw(struct vcpu *v)
+{
+    RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc;
+    if ( (s->cmos_data[RTC_REG_A] & RTC_RATE_SELECT) /* Period is not zero */
+         && (s->cmos_data[RTC_REG_B] & RTC_PIE) ) 
+        set_timer(&s->pie_timer, s->next_pie);
+}
+
+/* Move the RTC timers on to this vcpu's current cpu */
+void rtc_migrate_timers(struct vcpu *v)
+{
+    RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc;
+    migrate_timer(&s->second_timer, v->processor);
+    migrate_timer(&s->second_timer2, v->processor);
+    migrate_timer(&s->pie_timer, v->processor);
+}
+
 void rtc_init(struct vcpu *v, int base, int irq)
 {
     RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc;
 
     s->vcpu = v;
     s->irq = irq;
-    s->cmos_data[RTC_REG_A] = 0x26;
-    s->cmos_data[RTC_REG_B] = 0x02;
-    s->cmos_data[RTC_REG_C] = 0x00;
-    s->cmos_data[RTC_REG_D] = 0x80;
+    s->cmos_data[RTC_REG_A] = RTC_REF_CLCK_32KHZ | 6; /* ~1kHz */
+    s->cmos_data[RTC_REG_B] = RTC_24H;
+    s->cmos_data[RTC_REG_C] = 0;
+    s->cmos_data[RTC_REG_D] = RTC_VRT;
 
     s->current_tm = gmtime(get_localtime(v->domain));
     rtc_copy_date(s);
 
     init_timer(&s->second_timer, rtc_update_second, s, v->processor);
     init_timer(&s->second_timer2, rtc_update_second2, s, v->processor);
+    init_timer(&s->pie_timer, rtc_pie_callback, s, v->processor);
 
     s->next_second_time = NOW() + 1000000000ULL;
     set_timer(&s->second_timer2, s->next_second_time);
@@ -390,4 +419,5 @@ void rtc_deinit(struct domain *d)
 
     kill_timer(&s->second_timer);
     kill_timer(&s->second_timer2);
-}
+    kill_timer(&s->pie_timer);
+}
diff -r 992723a0ceb1 -r 5f7b5e5ca14b xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Thu Nov 16 15:20:05 2006 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c        Thu Nov 16 17:07:23 2006 +0000
@@ -723,7 +723,10 @@ static void svm_freeze_time(struct vcpu 
             && !v->arch.hvm_vcpu.guest_time ) {
         v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v);
         if ( test_bit(_VCPUF_blocked, &v->vcpu_flags) )
+        {
             stop_timer(&pt->timer);
+            rtc_freeze(v);
+        }
     }
 }
 
@@ -850,24 +853,6 @@ int start_svm(void)
 }
 
 
-static void svm_migrate_timers(struct vcpu *v)
-{
-    struct periodic_time *pt = 
-        &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
-    struct RTCState *vrtc = &v->domain->arch.hvm_domain.pl_time.vrtc;
-    struct PMTState *vpmt = &v->domain->arch.hvm_domain.pl_time.vpmt;
-
-    if ( pt->enabled )
-    {
-        migrate_timer(&pt->timer, v->processor);
-    }
-    migrate_timer(&vcpu_vlapic(v)->vlapic_timer, v->processor);
-    migrate_timer(&vrtc->second_timer, v->processor);
-    migrate_timer(&vrtc->second_timer2, v->processor);
-    migrate_timer(&vpmt->timer, v->processor);
-}
-
-
 void arch_svm_do_resume(struct vcpu *v) 
 {
     /* pinning VCPU to a different core? */
@@ -880,7 +865,7 @@ void arch_svm_do_resume(struct vcpu *v)
             printk("VCPU core pinned: %d to %d\n", 
                    v->arch.hvm_svm.launch_core, smp_processor_id() );
         v->arch.hvm_svm.launch_core = smp_processor_id();
-        svm_migrate_timers( v );
+        hvm_migrate_timers( v );
         hvm_do_resume( v );
         reset_stack_and_jump( svm_asm_do_resume );
     }
diff -r 992723a0ceb1 -r 5f7b5e5ca14b xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c        Thu Nov 16 15:20:05 2006 +0000
+++ b/xen/arch/x86/hvm/vioapic.c        Thu Nov 16 17:07:23 2006 +0000
@@ -471,8 +471,8 @@ void vioapic_set_irq(struct domain *d, i
     struct vioapic *vioapic = domain_vioapic(d);
     uint32_t bit;
 
-    HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_set_irq "
-                "irq %x level %x\n", irq, level);
+    HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_set_irq irq %x level %x", 
+                irq, level);
 
     if ( (irq < 0) || (irq >= VIOAPIC_NUM_PINS) )
         return;
diff -r 992723a0ceb1 -r 5f7b5e5ca14b xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Thu Nov 16 15:20:05 2006 +0000
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Thu Nov 16 17:07:23 2006 +0000
@@ -486,7 +486,7 @@ void arch_vmx_do_resume(struct vcpu *v)
     {
         vmx_clear_vmcs(v);
         vmx_load_vmcs(v);
-        vmx_migrate_timers(v);
+        hvm_migrate_timers(v);
         vmx_set_host_env(v);
     }
 
diff -r 992723a0ceb1 -r 5f7b5e5ca14b xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Thu Nov 16 15:20:05 2006 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Thu Nov 16 17:07:23 2006 +0000
@@ -376,14 +376,18 @@ static inline void vmx_restore_dr(struct
 
 static void vmx_freeze_time(struct vcpu *v)
 {
-    struct periodic_time *pt=&v->domain->arch.hvm_domain.pl_time.periodic_tm;
+    struct hvm_domain *plat = &v->domain->arch.hvm_domain;
+    struct periodic_time *pt = &plat->pl_time.periodic_tm;
 
     if ( pt->enabled && pt->first_injected
             && (v->vcpu_id == pt->bind_vcpu)
             && !v->arch.hvm_vcpu.guest_time ) {
         v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v);
         if ( !test_bit(_VCPUF_blocked, &v->vcpu_flags) )
+        {
             stop_timer(&pt->timer);
+            rtc_freeze(v);
+        }
     }
 }
 
@@ -407,22 +411,6 @@ static void stop_vmx(void)
         return;
     __vmxoff();
     clear_in_cr4(X86_CR4_VMXE);
-}
-
-void vmx_migrate_timers(struct vcpu *v)
-{
-    struct periodic_time *pt = &v->domain->arch.hvm_domain.pl_time.periodic_tm;
-    struct RTCState *vrtc = &v->domain->arch.hvm_domain.pl_time.vrtc;
-    struct PMTState *vpmt = &v->domain->arch.hvm_domain.pl_time.vpmt;
-
-    if ( pt->enabled )
-    {
-        migrate_timer(&pt->timer, v->processor);
-    }
-    migrate_timer(&vcpu_vlapic(v)->vlapic_timer, v->processor);
-    migrate_timer(&vrtc->second_timer, v->processor);
-    migrate_timer(&vrtc->second_timer2, v->processor);
-    migrate_timer(&vpmt->timer, v->processor);
 }
 
 static void vmx_store_cpu_guest_regs(
diff -r 992723a0ceb1 -r 5f7b5e5ca14b xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Thu Nov 16 15:20:05 2006 +0000
+++ b/xen/include/asm-x86/hvm/hvm.h     Thu Nov 16 17:07:23 2006 +0000
@@ -161,6 +161,7 @@ hvm_get_guest_ctrl_reg(struct vcpu *v, u
 
 void hvm_stts(struct vcpu *v);
 void hvm_set_guest_time(struct vcpu *v, u64 gtime);
+void hvm_migrate_timers(struct vcpu *v);
 void hvm_do_resume(struct vcpu *v);
 
 static inline void
diff -r 992723a0ceb1 -r 5f7b5e5ca14b xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Thu Nov 16 15:20:05 2006 +0000
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Thu Nov 16 17:07:23 2006 +0000
@@ -29,7 +29,6 @@ extern void vmx_asm_vmexit_handler(struc
 extern void vmx_asm_vmexit_handler(struct cpu_user_regs);
 extern void vmx_asm_do_vmentry(void);
 extern void vmx_intr_assist(void);
-extern void vmx_migrate_timers(struct vcpu *v);
 extern void arch_vmx_do_resume(struct vcpu *);
 extern void set_guest_time(struct vcpu *v, u64 gtime);
 
diff -r 992723a0ceb1 -r 5f7b5e5ca14b xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h     Thu Nov 16 15:20:05 2006 +0000
+++ b/xen/include/asm-x86/hvm/vpt.h     Thu Nov 16 17:07:23 2006 +0000
@@ -67,8 +67,10 @@ typedef struct RTCState {
     int64_t next_second_time;
     struct timer second_timer;
     struct timer second_timer2;
+    struct timer pie_timer;
+    int period;
+    s_time_t next_pie;
     struct vcpu      *vcpu;
-    struct periodic_time *pt;
 } RTCState;
 
 #define FREQUENCE_PMTIMER  3579545
@@ -143,9 +145,11 @@ void pit_init(struct vcpu *v, unsigned l
 void pit_init(struct vcpu *v, unsigned long cpu_khz);
 void rtc_init(struct vcpu *v, int base, int irq);
 void rtc_deinit(struct domain *d);
+void rtc_freeze(struct vcpu *v);
+void rtc_thaw(struct vcpu *v);
+void rtc_migrate_timers(struct vcpu *v);
 void pmtimer_init(struct vcpu *v, int base);
 void pmtimer_deinit(struct domain *d);
-int is_rtc_periodic_irq(void *opaque);
 void pt_timer_fn(void *data);
 void pit_time_fired(struct vcpu *v, void *priv);
 

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [HVM] Decouple the RTC from the PIT periodic timer, Xen patchbot-unstable <=