Mailing List Archive

[IA64] Add event injection logic
# HG changeset patch
# User awilliam@xenbuild.aw
# 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@intel.com>
---
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@lists.xensource.com
http://lists.xensource.com/xen-changelog