From: kaf24@firebug.cl.cam.ac.uk Date: Tue, 27 Jun 2006 14:38:32 +0000 (+0100) Subject: [HVM] Fix virtual apic irq distribution. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~15913^2~12 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=c8e79412c0010b94651f8d1481fb8f2a4a9216d0;p=xen.git [HVM] Fix virtual apic irq distribution. But currently we inject PIT irqs to cpu0 only. Also mute some warning messages. Signed-off-by: Yunhong Jiang Signed-off-by: Xin Li Signed-off-by: Keir Fraser --- diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c index d868f3092d..cf50014380 100644 --- a/xen/arch/x86/hvm/vioapic.c +++ b/xen/arch/x86/hvm/vioapic.c @@ -40,6 +40,9 @@ #include #include +/* HACK: Route IRQ0 only to VCPU0 to prevent time jumps. */ +#define IRQ0_SPECIAL_ROUTING 1 + #if defined(__ia64__) #define opt_hvm_debug_level opt_vmx_debug_level #endif @@ -392,12 +395,12 @@ static void ioapic_deliver(hvm_vioapic_t *s, int irqno) uint8_t trig_mode = s->redirtbl[irqno].RedirForm.trigmod; uint32_t deliver_bitmask; - HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "IOAPIC deliver: " + HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "dest %x dest_mode %x delivery_mode %x vector %x trig_mode %x\n", dest, dest_mode, delivery_mode, vector, trig_mode); - deliver_bitmask = - ioapic_get_delivery_bitmask(s, dest, dest_mode, vector, delivery_mode); + deliver_bitmask = ioapic_get_delivery_bitmask( + s, dest, dest_mode, vector, delivery_mode); if (!deliver_bitmask) { HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic deliver " @@ -411,15 +414,19 @@ static void ioapic_deliver(hvm_vioapic_t *s, int irqno) { struct vlapic* target; - target = apic_round_robin( - s->domain, dest_mode, vector, deliver_bitmask); +#ifdef IRQ0_SPECIAL_ROUTING + if (irqno == 0) + target = s->lapic_info[0]; + else +#endif + target = apic_round_robin(s->domain, dest_mode, + vector, deliver_bitmask); if (target) ioapic_inj_irq(s, target, vector, trig_mode, delivery_mode); - else{ - HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic deliver " + else + HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "null round robin mask %x vector %x delivery_mode %x\n", deliver_bitmask, vector, deliver_bitmask); - } break; } @@ -429,6 +436,13 @@ static void ioapic_deliver(hvm_vioapic_t *s, int irqno) uint8_t bit; for (bit = 0; bit < s->lapic_count; bit++) { if (deliver_bitmask & (1 << bit)) { +#ifdef IRQ0_SPECIAL_ROUTING + if ( (irqno == 0) && (bit !=0) ) + { + printk("PIT irq to bit %x\n", bit); + domain_crash_synchronous(); + } +#endif if (s->lapic_info[bit]) { ioapic_inj_irq(s, s->lapic_info[bit], vector, trig_mode, delivery_mode); diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c index af50550c53..900a98e485 100644 --- a/xen/arch/x86/hvm/vlapic.c +++ b/xen/arch/x86/hvm/vlapic.c @@ -212,18 +212,19 @@ static int vlapic_accept_irq(struct vcpu *v, int delivery_mode, if ( test_and_set_bit(vector, &vlapic->irr[0]) ) { - printk("" - "level trig mode repeatedly for vector %d\n", vector); + HVM_DBG_LOG(DBG_LEVEL_VLAPIC, + "level trig mode repeatedly for vector %d\n", vector); break; } if ( level ) { - printk(" level trig mode for vector %d\n", - vector); + HVM_DBG_LOG(DBG_LEVEL_VLAPIC, + "level trig mode for vector %d\n", vector); set_bit(vector, &vlapic->tmr[0]); } evtchn_set_pending(v, iopacket_port(v)); + result = 1; break; @@ -308,8 +309,15 @@ struct vlapic* apic_round_robin(struct domain *d, old = next = d->arch.hvm_domain.round_info[vector]; - do { - /* the vcpu array is arranged according to vcpu_id */ + /* the vcpu array is arranged according to vcpu_id */ + do + { + next++; + if ( !d->vcpu[next] || + !test_bit(_VCPUF_initialised, &d->vcpu[next]->vcpu_flags) || + next == MAX_VIRT_CPUS ) + next = 0; + if ( test_bit(next, &bitmap) ) { target = d->vcpu[next]->arch.hvm_vcpu.vlapic; @@ -321,12 +329,6 @@ struct vlapic* apic_round_robin(struct domain *d, } break; } - - next ++; - if ( !d->vcpu[next] || - !test_bit(_VCPUF_initialised, &d->vcpu[next]->vcpu_flags) || - next == MAX_VIRT_CPUS ) - next = 0; } while ( next != old ); d->arch.hvm_domain.round_info[vector] = next; @@ -956,7 +958,7 @@ int cpu_has_apic_interrupt(struct vcpu* v) } return 0; } - + void vlapic_post_injection(struct vcpu *v, int vector, int deliver_mode) { struct vlapic *vlapic = VLAPIC(v);