[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Fix IPI handling before vcpu launched
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID bee09e2200ab0386437e8824c152ad2ae7541f68 # Parent de41f5e24cf1b39a57ad343c84e2221ad62b9afa Fix IPI handling before vcpu launched When sending IPI, the target vcpu may not be launched (like INIT/Start-Up IPI), and the local apic is not initialized. Fix handling on such case. Also fix one bug in apic_round_robin function. Signed-off-by: Yunhong Jiang <yunhong.jiang@xxxxxxxxx> Signed-off-by: Xin Li <xin.b.li@xxxxxxxxx> diff -r de41f5e24cf1 -r bee09e2200ab xen/arch/x86/vmx_vlapic.c --- a/xen/arch/x86/vmx_vlapic.c Thu Nov 10 11:09:17 2005 +++ b/xen/arch/x86/vmx_vlapic.c Thu Nov 10 11:11:39 2005 @@ -119,22 +119,35 @@ } /* This only for fixed delivery mode */ -int vlapic_match_dest(struct vlapic *target, struct vlapic *source, - int short_hand, int dest, int dest_mode, - int delivery_mode) +static int vlapic_match_dest(struct vcpu *v, struct vlapic *source, + int short_hand, int dest, int dest_mode, + int delivery_mode) { int result = 0; + struct vlapic *target = VLAPIC(v); VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_match_dest: " "target %p source %p dest %x dest_mode %x short_hand %x " "delivery_mode %x", target, source, dest, dest_mode, short_hand, delivery_mode); + if ( unlikely(!target) && + ( (delivery_mode != VLAPIC_DELIV_MODE_INIT) && + (delivery_mode != VLAPIC_DELIV_MODE_STARTUP) && + (delivery_mode != VLAPIC_DELIV_MODE_NMI) )) { + VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_match_dest " + "uninitialized target v %p delivery_mode %x dest %x\n", + v, delivery_mode, dest); + return result; + } + switch (short_hand) { case VLAPIC_NO_SHORTHAND: if (!dest_mode) { /* Physical */ - result = (target->id == dest); + result = ((target ? target->id : v->vcpu_id ) == dest); } else { /* Logical */ + if (!target) + break; if (((target->dest_format >> 28) & 0xf) == 0xf) { /* Flat mode */ result = (target->logical_dest >> 24) & dest; } else { @@ -176,17 +189,18 @@ * Add a pending IRQ into lapic. * Return 1 if successfully added and 0 if discarded. */ -int vlapic_accept_irq(struct vlapic *vlapic, int delivery_mode, - int vector, int level, int trig_mode) -{ - int result = 1; +static int vlapic_accept_irq(struct vcpu *v, int delivery_mode, + int vector, int level, int trig_mode) +{ + int result = 0; + struct vlapic *vlapic = VLAPIC(v); switch (delivery_mode) { case VLAPIC_DELIV_MODE_FIXED: case VLAPIC_DELIV_MODE_LPRI: /* FIXME add logic for vcpu on reset */ - if (!vlapic->vcpu || !vlapic_enabled(vlapic)) - return 0; + if (unlikely(!vlapic || !vlapic_enabled(vlapic))) + return result; if (test_and_set_bit(vector, &vlapic->irr[0])) { printk("<vlapic_accept_irq>" @@ -199,6 +213,7 @@ } } evtchn_set_pending(vlapic->vcpu, iopacket_port(vlapic->domain)); + result = 1; break; case VLAPIC_DELIV_MODE_RESERVED: @@ -269,15 +284,12 @@ old = next = d->arch.vmx_platform.round_info[vector]; - next++; - if (next == MAX_VIRT_CPUS || !d->vcpu[next]) - next = 0; - do { /* the vcpu array is arranged according to vcpu_id */ if (test_bit(next, &bitmap)) { target = d->vcpu[next]->arch.arch_vmx.vlapic; - if (!vlapic_enabled(target)) { + + if (!target || !vlapic_enabled(target)) { printk("warning: targe round robin local apic disabled\n"); /* XXX should we domain crash?? Or should we return NULL */ } @@ -285,7 +297,9 @@ } next ++; - if (next == MAX_VIRT_CPUS || !d->vcpu[next]) + if (!d->vcpu[next] || + !test_bit(_VCPUF_initialised, &d->vcpu[next]->vcpu_flags) || + next == MAX_VIRT_CPUS) next = 0; }while(next != old); @@ -319,7 +333,7 @@ { if ((dm == VLAPIC_DELIV_MODE_FIXED) && (vector < 16)) { vlapic->err_status |= 0x40; - vlapic_accept_irq(vlapic, VLAPIC_DELIV_MODE_FIXED, + vlapic_accept_irq(vlapic->vcpu, VLAPIC_DELIV_MODE_FIXED, vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR), 0, 0); printk("<vlapic_check_vector>: check fail\n"); return 0; @@ -340,7 +354,6 @@ struct vlapic *target; struct vcpu *v = NULL; - int result = 0; uint32_t lpr_map; VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_ipi: " @@ -352,32 +365,27 @@ delivery_mode, vector); for_each_vcpu ( vlapic->domain, v ) { - target = VLAPIC(v); - if (vlapic_match_dest(target, vlapic, short_hand, + if (vlapic_match_dest(v, vlapic, short_hand, dest, dest_mode, delivery_mode)) { if (delivery_mode == VLAPIC_DELIV_MODE_LPRI) { set_bit(v->vcpu_id, &lpr_map); - }else - result = vlapic_accept_irq(target, delivery_mode, - vector, level, trig_mode); + } else + vlapic_accept_irq(v, delivery_mode, + vector, level, trig_mode); } } if (delivery_mode == VLAPIC_DELIV_MODE_LPRI) { - extern struct vlapic* - apic_round_robin(struct domain *d, - uint8_t dest_mode, uint8_t vector, uint32_t bitmap); - v = vlapic->vcpu; target = apic_round_robin(v->domain, dest_mode, vector, lpr_map); if (target) - vlapic_accept_irq(target, delivery_mode, - vector, level, trig_mode); - } -} - -void vlapic_begin_timer(struct vlapic *vlapic) + vlapic_accept_irq(target->vcpu, delivery_mode, + vector, level, trig_mode); + } +} + +static void vlapic_begin_timer(struct vlapic *vlapic) { s_time_t cur = NOW(), offset; @@ -737,12 +745,13 @@ vlapic->timer_current = val; vlapic->timer_current_update = NOW(); + vlapic_begin_timer(vlapic); + VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "timer_init %x timer_current %x" "timer_current_update %08x%08x", vlapic->timer_initial, vlapic->timer_current, (uint32_t)(vlapic->timer_current_update >> 32), (uint32_t)vlapic->timer_current_update); - vlapic_begin_timer(vlapic); break; case APIC_TDCR: @@ -827,6 +836,7 @@ } else vlapic->intr_pending_count[vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER)]++; + evtchn_set_pending(vlapic->vcpu, iopacket_port(vlapic->domain)); } vlapic->timer_current_update = NOW(); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |