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] [IA64] Fix Windows Timer stop issue.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [IA64] Fix Windows Timer stop issue.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 26 Oct 2006 12:11:28 +0000
Delivery-date: Thu, 26 Oct 2006 05:18:50 -0700
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 awilliam@xxxxxxxxxxx
# Node ID d5a46e4cc340dfaf6c638a64ae536d917065e2ba
# Parent  a7c6b1c5507c4365862d171edb7feb7a84c25060
[IA64] Fix Windows Timer stop issue.

When doing HCT testing on Guest Windows, Windows Timer might stop,
if there is no mouse activity.

When implementing vhpi acceleration, I didn't think of below situation.
windows uses "epc" instruction to implement system call like linux,
In a very small code sequence including "epc" instruction, if there is 
an external interrupt, Windows will defer handling this external interrupt
by rfi with ipsr.i=0.

Signed-off-by, Anthony Xu <anthony.xu@xxxxxxxxx>
---
 xen/arch/ia64/vmx/vlsapic.c     |  159 +++++++++++++++++++++-------------------
 xen/arch/ia64/vmx/vmx_process.c |    5 -
 xen/arch/ia64/xen/xentime.c     |   43 ++++------
 3 files changed, 105 insertions(+), 102 deletions(-)

diff -r a7c6b1c5507c -r d5a46e4cc340 xen/arch/ia64/vmx/vlsapic.c
--- a/xen/arch/ia64/vmx/vlsapic.c       Sun Oct 22 14:14:58 2006 -0600
+++ b/xen/arch/ia64/vmx/vlsapic.c       Sun Oct 22 14:39:15 2006 -0600
@@ -57,6 +57,59 @@ static void update_last_itc(vtime_t *vtm
 }
 
 /*
+ * Next for vLSapic
+ */
+
+#define NMI_VECTOR             2
+#define ExtINT_VECTOR          0
+#define NULL_VECTOR            -1
+
+static void update_vhpi(VCPU *vcpu, int vec)
+{
+    u64 vhpi;
+
+    if (vec == NULL_VECTOR)
+        vhpi = 0;
+    else if (vec == NMI_VECTOR)
+        vhpi = 32;
+    else if (vec == ExtINT_VECTOR)
+        vhpi = 16;
+    else
+        vhpi = vec >> 4;
+
+    VCPU(vcpu,vhpi) = vhpi;
+    // TODO: Add support for XENO
+    if (VCPU(vcpu,vac).a_int)
+        ia64_call_vsa(PAL_VPS_SET_PENDING_INTERRUPT, 
+                      (uint64_t)vcpu->arch.privregs, 0, 0, 0, 0, 0, 0);
+}
+
+
+/*
+ * May come from virtualization fault or
+ * nested host interrupt.
+ */
+static int vmx_vcpu_unpend_interrupt(VCPU *vcpu, uint8_t vector)
+{
+    uint64_t spsr;
+    int ret;
+
+    if (vector & ~0xff) {
+        DPRINTK("vmx_vcpu_pend_interrupt: bad vector\n");
+        return -1;
+    }
+
+    local_irq_save(spsr);
+    ret = test_and_clear_bit(vector, &VCPU(vcpu, irr[0]));
+    local_irq_restore(spsr);
+
+    if (ret)
+        vcpu->arch.irq_new_pending = 1;
+
+    return ret;
+}
+
+/*
  * ITC value saw in guest (host+offset+drift).
  */
 static uint64_t now_itc(vtime_t *vtm)
@@ -107,9 +160,6 @@ static void vtm_timer_fn(void *data)
     }
     vtm=&(vcpu->arch.arch_vmx.vtm);
     cur_itc = now_itc(vtm);
- //    vitm =VCPU(vcpu, itm);
- //fire_itc2 = cur_itc;
- //fire_itm2 = vitm;
     update_last_itc(vtm,cur_itc);  // pseudo read to update vITC
 }
 
@@ -137,6 +187,7 @@ uint64_t vtm_get_itc(VCPU *vcpu)
 
     vtm=&(vcpu->arch.arch_vmx.vtm);
     guest_itc = now_itc(vtm);
+    update_last_itc(vtm, guest_itc);  // update vITC
     return guest_itc;
 }
 
@@ -158,7 +209,7 @@ void vtm_set_itc(VCPU *vcpu, uint64_t ne
         vtm->last_itc = new_itc;
     }
     if(vitm < new_itc){
-        clear_bit(ITV_VECTOR(vitv), &VCPU(vcpu, irr[0]));
+        vmx_vcpu_unpend_interrupt(vcpu, ITV_VECTOR(vitv));
         stop_timer(&vtm->vtm_timer);
     }
 }
@@ -175,12 +226,12 @@ void vtm_set_itm(VCPU *vcpu, uint64_t va
     vitv = VCPU(vcpu, itv);
     vtm=&(vcpu->arch.arch_vmx.vtm);
     // TODO; need to handle VHPI in future
-    clear_bit(ITV_VECTOR(vitv), &VCPU(vcpu, irr[0]));
+    vmx_vcpu_unpend_interrupt(vcpu, ITV_VECTOR(vitv));
     VCPU(vcpu,itm)=val;
-    cur_itc =now_itc(vtm);
-    if(time_before(val, cur_itc))
-        val = cur_itc;
-    if(val >  vtm->last_itc){
+    if (val >= vtm->last_itc) {
+        cur_itc = now_itc(vtm);
+        if (time_before(val, cur_itc))
+            val = cur_itc;
         expires = NOW() + cycle_to_ns(val-cur_itc) + TIMER_SLOP;
         set_timer(&vtm->vtm_timer, expires);
     }else{
@@ -195,10 +246,10 @@ void vtm_set_itv(VCPU *vcpu, uint64_t va
     olditv = VCPU(vcpu, itv);
     VCPU(vcpu, itv) = val;
     if(ITV_IRQ_MASK(val)){
-        clear_bit(ITV_VECTOR(olditv), &VCPU(vcpu, irr[0]));
+        vmx_vcpu_unpend_interrupt(vcpu, ITV_VECTOR(olditv));
     }else if(ITV_VECTOR(olditv)!=ITV_VECTOR(val)){
-        if(test_and_clear_bit(ITV_VECTOR(olditv), &VCPU(vcpu, irr[0])))
-            set_bit(ITV_VECTOR(val), &VCPU(vcpu, irr[0]));
+        if (vmx_vcpu_unpend_interrupt(vcpu, ITV_VECTOR(olditv)))
+            vmx_vcpu_pend_interrupt(vcpu, ITV_VECTOR(val));
     }
 }
 
@@ -271,36 +322,6 @@ void vtm_domain_in(VCPU *vcpu)
     }
 }
  */
-
-/*
- * Next for vLSapic
- */
-
-#define  NMI_VECTOR         2
-#define  ExtINT_VECTOR      0
-#define  NULL_VECTOR        -1
-static void update_vhpi(VCPU *vcpu, int vec)
-{
-    u64     vhpi;
-    if ( vec == NULL_VECTOR ) {
-        vhpi = 0;
-    }
-    else if ( vec == NMI_VECTOR ) { // NMI
-        vhpi = 32;
-    } else if (vec == ExtINT_VECTOR) { //ExtINT
-        vhpi = 16;
-    }
-    else {
-        vhpi = vec >> 4;
-    }
-
-    VCPU(vcpu,vhpi) = vhpi;
-    // TODO: Add support for XENO
-    if ( VCPU(vcpu,vac).a_int ) {
-        ia64_call_vsa ( PAL_VPS_SET_PENDING_INTERRUPT, 
-                (uint64_t)vcpu->arch.privregs, 0, 0, 0, 0, 0, 0);
-    }
-}
 
 #ifdef V_IOSAPIC_READY
 /* Assist to check virtual interrupt lines */
@@ -524,9 +545,13 @@ int vmx_vcpu_pend_interrupt(VCPU *vcpu, 
     local_irq_save(spsr);
     ret = test_and_set_bit(vector, &VCPU(vcpu, irr[0]));
     local_irq_restore(spsr);
-    vcpu->arch.irq_new_pending = 1;
+
+    if (!ret)
+        vcpu->arch.irq_new_pending = 1;
+
     return ret;
 }
+
 
 /*
  * Add batch of pending interrupt.
@@ -559,14 +584,13 @@ void vmx_vcpu_pend_batch_interrupt(VCPU 
  */
 int vmx_check_pending_irq(VCPU *vcpu)
 {
-    uint64_t  spsr, mask;
-    int     h_pending, h_inservice;
-    uint64_t    isr;
-    IA64_PSR    vpsr;
+    int  mask, h_pending, h_inservice;
+    uint64_t isr;
+    IA64_PSR vpsr;
     REGS *regs=vcpu_regs(vcpu);
-    local_irq_save(spsr);
     h_pending = highest_pending_irq(vcpu);
     if ( h_pending == NULL_VECTOR ) {
+        update_vhpi(vcpu, NULL_VECTOR);
         h_pending = SPURIOUS_VECTOR;
         goto chk_irq_exit;
     }
@@ -578,13 +602,11 @@ int vmx_check_pending_irq(VCPU *vcpu)
         isr = vpsr.val & IA64_PSR_RI;
         if ( !vpsr.ic )
             panic_domain(regs,"Interrupt when IC=0\n");
+        update_vhpi(vcpu, h_pending);
+        vmx_reflect_interruption(0, isr, 0, 12, regs); // EXT IRQ
+    } else if (mask == IRQ_MASKED_BY_INSVC) {
         if (VCPU(vcpu, vhpi))
             update_vhpi(vcpu, NULL_VECTOR);
-        vmx_reflect_interruption(0,isr,0, 12, regs ); // EXT IRQ
-    }
-    else if ( mask == IRQ_MASKED_BY_INSVC ) {
-        // cann't inject VHPI
-//        DPRINTK("IRQ masked by higher inservice\n");
     }
     else {
         // masked by vpsr.i or vtpr.
@@ -592,7 +614,6 @@ int vmx_check_pending_irq(VCPU *vcpu)
     }
 
 chk_irq_exit:
-    local_irq_restore(spsr);
     return h_pending;
 }
 
@@ -602,17 +623,13 @@ void guest_write_eoi(VCPU *vcpu)
 void guest_write_eoi(VCPU *vcpu)
 {
     int vec;
-    uint64_t  spsr;
 
     vec = highest_inservice_irq(vcpu);
     if ( vec == NULL_VECTOR ) 
-       panic_domain(vcpu_regs(vcpu),"Wrong vector to EOI\n");
-    local_irq_save(spsr);
+        panic_domain(vcpu_regs(vcpu), "Wrong vector to EOI\n");
     VLSAPIC_INSVC(vcpu,vec>>6) &= ~(1UL <<(vec&63));
-    local_irq_restore(spsr);
     VCPU(vcpu, eoi)=0;    // overwrite the data
     vcpu->arch.irq_new_pending=1;
-//    vmx_check_pending_irq(vcpu);
 }
 
 int is_unmasked_irq(VCPU *vcpu)
@@ -631,23 +648,21 @@ int is_unmasked_irq(VCPU *vcpu)
 
 uint64_t guest_read_vivr(VCPU *vcpu)
 {
-    int vec, h_inservice;
-    uint64_t  spsr;
-
-    local_irq_save(spsr);
+    int vec, h_inservice, mask;
     vec = highest_pending_irq(vcpu);
     h_inservice = highest_inservice_irq(vcpu);
-    if ( vec == NULL_VECTOR || 
-        irq_masked(vcpu, vec, h_inservice) != IRQ_NO_MASKED ) {
-        local_irq_restore(spsr);
+    mask = irq_masked(vcpu, vec, h_inservice);
+    if (vec == NULL_VECTOR || mask == IRQ_MASKED_BY_INSVC) {
+        if (VCPU(vcpu, vhpi))
+            update_vhpi(vcpu, NULL_VECTOR);
         return IA64_SPURIOUS_INT_VECTOR;
     }
- 
+    if (mask == IRQ_MASKED_BY_VTPR) {
+        update_vhpi(vcpu, vec);
+        return IA64_SPURIOUS_INT_VECTOR;
+    }
     VLSAPIC_INSVC(vcpu,vec>>6) |= (1UL <<(vec&63));
-    VCPU(vcpu, irr[vec>>6]) &= ~(1UL <<(vec&63));
-    if (VCPU(vcpu, vhpi))
-        update_vhpi(vcpu, NULL_VECTOR); // clear VHPI till EOI or IRR write
-    local_irq_restore(spsr);
+    vmx_vcpu_unpend_interrupt(vcpu, vec);
     return (uint64_t)vec;
 }
 
@@ -657,7 +672,6 @@ static void generate_exirq(VCPU *vcpu)
     uint64_t    isr;
     REGS *regs=vcpu_regs(vcpu);
     vpsr.val = VCPU(vcpu, vpsr);
-    update_vhpi(vcpu, NULL_VECTOR);
     isr = vpsr.val & IA64_PSR_RI;
     if ( !vpsr.ic )
         panic_domain(regs,"Interrupt when IC=0\n");
@@ -669,7 +683,6 @@ void vhpi_detection(VCPU *vcpu)
     uint64_t    threshold,vhpi;
     tpr_t       vtpr;
     IA64_PSR    vpsr;
-    
     vpsr.val = VCPU(vcpu, vpsr);
     vtpr.val = VCPU(vcpu, tpr);
 
diff -r a7c6b1c5507c -r d5a46e4cc340 xen/arch/ia64/vmx/vmx_process.c
--- a/xen/arch/ia64/vmx/vmx_process.c   Sun Oct 22 14:14:58 2006 -0600
+++ b/xen/arch/ia64/vmx/vmx_process.c   Sun Oct 22 14:39:15 2006 -0600
@@ -242,10 +242,7 @@ void leave_hypervisor_tail(struct pt_reg
             vmx_check_pending_irq(v);
             return;
         }
-        if (VCPU(v, vac).a_int) {
-            vhpi_detection(v);
-            return;
-        }
+
         if (v->arch.irq_new_condition) {
             v->arch.irq_new_condition = 0;
             vhpi_detection(v);
diff -r a7c6b1c5507c -r d5a46e4cc340 xen/arch/ia64/xen/xentime.c
--- a/xen/arch/ia64/xen/xentime.c       Sun Oct 22 14:14:58 2006 -0600
+++ b/xen/arch/ia64/xen/xentime.c       Sun Oct 22 14:39:15 2006 -0600
@@ -109,7 +109,6 @@ xen_timer_interrupt (int irq, void *dev_
 xen_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
 {
        unsigned long new_itm, old_itc;
-       int f_setitm = 0;
 
 #if 0
 #define HEARTBEAT_FREQ 16      // period in seconds
@@ -125,20 +124,9 @@ xen_timer_interrupt (int irq, void *dev_
 #endif
 #endif
 
-       if (!is_idle_domain(current->domain)&&!VMX_DOMAIN(current))
-               if (vcpu_timer_expired(current)) {
-                       vcpu_pend_timer(current);
-                       // ensure another timer interrupt happens even if 
domain doesn't
-                       vcpu_set_next_timer(current);
-                       f_setitm = 1;
-               }
 
        new_itm = local_cpu_data->itm_next;
-
-       if (f_setitm && !time_after(ia64_get_itc(), new_itm)) 
-               return;
-
-       while (1) {
+       while (time_after(ia64_get_itc(), new_itm)) {
                new_itm += local_cpu_data->itm_delta;
 
                if (smp_processor_id() == TIME_KEEPER_ID) {
@@ -148,27 +136,32 @@ xen_timer_interrupt (int irq, void *dev_
                         * another CPU. We need to avoid to SMP race by 
acquiring the
                         * xtime_lock.
                         */
-//#ifdef TURN_ME_OFF_FOR_NOW_IA64_XEN
                        write_seqlock(&xtime_lock);
-//#endif
 #ifdef TURN_ME_OFF_FOR_NOW_IA64_XEN
                        do_timer(regs);
 #endif
-                       local_cpu_data->itm_next = new_itm;
-
-                       /* Updates system time (nanoseconds since boot). */
+                       /* Updates system time (nanoseconds since boot). */
                        old_itc = itc_at_irq;
                        itc_at_irq = ia64_get_itc();
                        stime_irq += cycle_to_ns(itc_at_irq - old_itc);
 
-//#ifdef TURN_ME_OFF_FOR_NOW_IA64_XEN
                        write_sequnlock(&xtime_lock);
-//#endif
-               } else
-                       local_cpu_data->itm_next = new_itm;
-
-               if (time_after(new_itm, ia64_get_itc()))
-                       break;
+               }
+
+               local_cpu_data->itm_next = new_itm;
+
+       }
+
+       if (!is_idle_domain(current->domain) && !VMX_DOMAIN(current)) {
+               if (vcpu_timer_expired(current)) {
+                       vcpu_pend_timer(current);
+               } else {
+                       // ensure another timer interrupt happens
+                       // even if domain doesn't
+                       vcpu_set_next_timer(current);
+                       raise_softirq(TIMER_SOFTIRQ);
+                       return;
+               }
        }
 
        do {

_______________________________________________
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] [IA64] Fix Windows Timer stop issue., Xen patchbot-unstable <=