From: Peter Dinda Date: Sat, 31 Jul 2010 01:15:18 +0000 (-0500) Subject: Fixed handling of the INTAK cycle for both apic and pic X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=9f049c5f96785b6aa3e284a244235712c4047c1b;p=palacios.git Fixed handling of the INTAK cycle for both apic and pic Now the apic will only note an interrupt is in service if it actually originated it, similar to the pic. I also added debugging prints to both apic and pic to indicate when they ignore such INTAK end-of-cycle INTAK -> begin_irq on interrupt controllers --- diff --git a/palacios/src/devices/8259a.c b/palacios/src/devices/8259a.c index 6931900..498ab76 100644 --- a/palacios/src/devices/8259a.c +++ b/palacios/src/devices/8259a.c @@ -315,7 +315,10 @@ static int pic_begin_irq(struct guest_info * info, void * private_data, int irq) if (!(state->master_elcr & (0x1 << irq))) { state->master_irr &= ~(0x1 << irq); } + } else { + PrintDebug("8259 PIC: (master) Ignoring begin_irq for %d since I don't own it\n",irq); } + } else { // This should always be true: See pic_get_intr_number if (((state->slave_irr & ~(state->slave_imr)) >> (irq - 8)) & 0x01) { @@ -324,7 +327,10 @@ static int pic_begin_irq(struct guest_info * info, void * private_data, int irq) if (!(state->slave_elcr & (0x1 << (irq - 8)))) { state->slave_irr &= ~(0x1 << (irq - 8)); } - } + } else { + PrintDebug("8259 PIC: (slave) Ignoring begin_irq for %d since I don't own it\n",irq); + } + } return 0; diff --git a/palacios/src/devices/apic.c b/palacios/src/devices/apic.c index db68669..73bee31 100644 --- a/palacios/src/devices/apic.c +++ b/palacios/src/devices/apic.c @@ -917,6 +917,8 @@ static int apic_intr_pending(struct guest_info * info, void * private_data) { int req_irq = get_highest_irr(apic); int svc_irq = get_highest_isr(apic); + PrintDebug("apic %u: core %u: req_irq=%d, svc_irq=%d\n",apic->lapic_id.val,info->cpu_id,req_irq,svc_irq); + if ((req_irq >= 0) && (req_irq > svc_irq)) { return 1; @@ -956,8 +958,16 @@ static int apic_begin_irq(struct guest_info * info, void * private_data, int irq uchar_t * svc_location = apic->int_svc_reg + major_offset; uchar_t flag = 0x01 << minor_offset; - *svc_location |= flag; - *req_location &= ~flag; + if (*req_location & flag) { + // we will only pay attention to a begin irq if we + // know that we initiated it! + *svc_location |= flag; + *req_location &= ~flag; + } else { + // do nothing... + PrintDebug("apic %u: core %u: begin irq for %d ignored since I don't own it\n", + apic->lapic_id.val,info->cpu_id,irq); + }