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

[Xen-changelog] [IA64] Add event injection logic



# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 2f2f500c26da0414ff307e8bfdefb80e99476faf
# Parent  d8659e39ff3cc8c147d6a5c2a13f7759a2ece27d
[IA64] Add event injection logic

Add event inject logic. Because up to this point there's no place
to register callback, this patch doesn't break existing working flow.

Signes-off-by Kevin Tian <kevin.tian@xxxxxxxxx>
---
 xen/arch/ia64/xen/process.c  |   35 ++++++++++++++++++++++++++++++++++-
 xen/arch/ia64/xen/vcpu.c     |   36 +++++++++++++++++++++++++-----------
 xen/include/asm-ia64/event.h |    4 ++--
 3 files changed, 61 insertions(+), 14 deletions(-)

diff -r d8659e39ff3c -r 2f2f500c26da xen/arch/ia64/xen/process.c
--- a/xen/arch/ia64/xen/process.c       Tue May 23 08:24:09 2006 -0600
+++ b/xen/arch/ia64/xen/process.c       Tue May 23 08:34:48 2006 -0600
@@ -246,6 +246,40 @@ printf("*#*#*#* about to deliver early t
        reflect_interruption(isr,regs,IA64_EXTINT_VECTOR);
 }
 
+void reflect_event(struct pt_regs *regs)
+{
+       unsigned long isr = regs->cr_ipsr & IA64_PSR_RI;
+       struct vcpu *v = current;
+
+       /* Sanity check */
+       if (is_idle_vcpu(v) || !user_mode(regs)) {
+               //printk("WARN: invocation to reflect_event in nested xen\n");
+               return;
+       }
+
+       if (!event_pending(v))
+               return;
+
+       if (!PSCB(v,interrupt_collection_enabled))
+               printf("psr.ic off, delivering event, 
ipsr=%lx,iip=%lx,isr=%lx,viip=0x%lx\n",
+                      regs->cr_ipsr, regs->cr_iip, isr, PSCB(v, iip));
+       PSCB(v,unat) = regs->ar_unat;  // not sure if this is really needed?
+       PSCB(v,precover_ifs) = regs->cr_ifs;
+       vcpu_bsw0(v);
+       PSCB(v,ipsr) = vcpu_get_ipsr_int_state(v,regs->cr_ipsr);
+       PSCB(v,isr) = isr;
+       PSCB(v,iip) = regs->cr_iip;
+       PSCB(v,ifs) = 0;
+       PSCB(v,incomplete_regframe) = 0;
+
+       regs->cr_iip = v->arch.event_callback_ip;
+       regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET;
+       regs->r31 = XSI_IPSR;
+
+       v->vcpu_info->evtchn_upcall_mask = 1;
+       PSCB(v,interrupt_collection_enabled) = 0;
+}
+
 // ONLY gets called from ia64_leave_kernel
 // ONLY call with interrupts disabled?? (else might miss one?)
 // NEVER successful if already reflecting a trap/fault because psr.i==0
@@ -255,7 +289,6 @@ void deliver_pending_interrupt(struct pt
        struct vcpu *v = current;
        // FIXME: Will this work properly if doing an RFI???
        if (!is_idle_domain(d) && user_mode(regs)) {
-               //vcpu_poke_timer(v);
                if (vcpu_deliverable_interrupts(v))
                        reflect_extint(regs);
                else if (PSCB(v,pending_interruption))
diff -r d8659e39ff3c -r 2f2f500c26da xen/arch/ia64/xen/vcpu.c
--- a/xen/arch/ia64/xen/vcpu.c  Tue May 23 08:24:09 2006 -0600
+++ b/xen/arch/ia64/xen/vcpu.c  Tue May 23 08:34:48 2006 -0600
@@ -649,16 +649,18 @@ void vcpu_pend_interrupt(VCPU *vcpu, UIN
                printf("vcpu_pend_interrupt: bad vector\n");
                return;
        }
-    if ( VMX_DOMAIN(vcpu) ) {
-           set_bit(vector,VCPU(vcpu,irr));
-    } else
-    {
-       if (test_bit(vector,PSCBX(vcpu,irr))) {
-//printf("vcpu_pend_interrupt: overrun\n");
-       }
-       set_bit(vector,PSCBX(vcpu,irr));
-       PSCB(vcpu,pending_interruption) = 1;
-    }
+
+       if (vcpu->arch.event_callback_ip) {
+               printf("Deprecated interface. Move to new event based 
solution\n");
+               return;
+       }
+               
+       if ( VMX_DOMAIN(vcpu) ) {
+               set_bit(vector,VCPU(vcpu,irr));
+       } else {
+               set_bit(vector,PSCBX(vcpu,irr));
+               PSCB(vcpu,pending_interruption) = 1;
+       }
 }
 
 #define        IA64_TPR_MMI    0x10000
@@ -673,6 +675,9 @@ UINT64 vcpu_check_pending_interrupts(VCP
 UINT64 vcpu_check_pending_interrupts(VCPU *vcpu)
 {
        UINT64 *p, *r, bits, bitnum, mask, i, vector;
+
+       if (vcpu->arch.event_callback_ip)
+               return SPURIOUS_VECTOR;
 
        /* Always check pending event, since guest may just ack the
         * event injection without handle. Later guest may throw out
@@ -1151,7 +1156,16 @@ void vcpu_pend_timer(VCPU *vcpu)
                // don't deliver another
                return;
        }
-       vcpu_pend_interrupt(vcpu, itv);
+       if (vcpu->arch.event_callback_ip) {
+               /* A small window may occur when injecting vIRQ while related
+                * handler has not been registered. Don't fire in such case.
+                */
+               if (vcpu->virq_to_evtchn[VIRQ_ITC]) {
+                       send_guest_vcpu_virq(vcpu, VIRQ_ITC);
+                       PSCBX(vcpu, domain_itm_last) = PSCBX(vcpu, domain_itm);
+               }
+       } else
+               vcpu_pend_interrupt(vcpu, itv);
 }
 
 // returns true if ready to deliver a timer interrupt too early
diff -r d8659e39ff3c -r 2f2f500c26da xen/include/asm-ia64/event.h
--- a/xen/include/asm-ia64/event.h      Tue May 23 08:24:09 2006 -0600
+++ b/xen/include/asm-ia64/event.h      Tue May 23 08:34:48 2006 -0600
@@ -28,8 +28,8 @@ static inline void evtchn_notify(struct 
     if ( running )
         smp_send_event_check_cpu(v->processor);
 
-    if(!VMX_DOMAIN(v))
-       vcpu_pend_interrupt(v, v->domain->shared_info->arch.evtchn_vector);
+    if(!VMX_DOMAIN(v) && !v->arch.event_callback_ip)
+        vcpu_pend_interrupt(v, v->domain->shared_info->arch.evtchn_vector);
 }
 
 /* Note: Bitwise operations result in fast code with no branches. */

_______________________________________________
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®.