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