diff options
author | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2006-11-08 15:11:18 +0000 |
---|---|---|
committer | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2006-11-08 15:11:18 +0000 |
commit | aa06b89d3b488d51bb3df2abaa183de4cffcc7b8 (patch) | |
tree | f9f3bce057ca9d82e8d472913c86fe769a86cf12 | |
parent | 6b8fe25df94080288678e746ea1b0071626e3aad (diff) | |
download | xen-aa06b89d3b488d51bb3df2abaa183de4cffcc7b8.tar.gz xen-aa06b89d3b488d51bb3df2abaa183de4cffcc7b8.tar.bz2 xen-aa06b89d3b488d51bb3df2abaa183de4cffcc7b8.zip |
[HVM] Simplify relationship between VIOAPIC and VLAPICs.
It's not really dynamic since there is always exactly
one VLAPIC per VCPU.
Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r-- | xen/arch/ia64/vmx/vlsapic.c | 17 | ||||
-rw-r--r-- | xen/arch/x86/hvm/vioapic.c | 115 | ||||
-rw-r--r-- | xen/arch/x86/hvm/vlapic.c | 2 | ||||
-rw-r--r-- | xen/include/asm-x86/hvm/vioapic.h | 8 |
4 files changed, 45 insertions, 97 deletions
diff --git a/xen/arch/ia64/vmx/vlsapic.c b/xen/arch/ia64/vmx/vlsapic.c index f53b78b6d5..49bdff0921 100644 --- a/xen/arch/ia64/vmx/vlsapic.c +++ b/xen/arch/ia64/vmx/vlsapic.c @@ -324,9 +324,9 @@ void vtm_domain_in(VCPU *vcpu) */ #ifdef V_IOSAPIC_READY -int ioapic_match_logical_addr(struct vioapic *s, int number, uint16_t dest) +int vlapic_match_logical_addr(struct vlapic *vlapic, uint16_t dest) { - return (VLAPIC_ID(s->lapic_info[number]) == dest); + return (VLAPIC_ID(vlapic) == dest); } struct vlapic* apic_round_robin(struct domain *d, @@ -334,21 +334,17 @@ struct vlapic* apic_round_robin(struct domain *d, uint8_t vector, uint32_t bitmap) { - uint8_t bit; - struct vioapic *s; + uint8_t bit = 0; if (!bitmap) { printk("<apic_round_robin> no bit on bitmap\n"); return NULL; } - s = domain_vioapic(d); - for (bit = 0; bit < s->lapic_count; bit++) { - if (bitmap & (1 << bit)) - return s->lapic_info[bit]; - } + while (!(bitmap & (1 << bit))) + bit++; - return NULL; + return vcpu_vlapic(d->vcpu[bit]); } #endif @@ -375,7 +371,6 @@ void vlsapic_reset(VCPU *vcpu) #ifdef V_IOSAPIC_READY vcpu->arch.arch_vmx.vlapic.vcpu = vcpu; - vioapic_add_lapic(&vcpu->arch.arch_vmx.vlapic, vcpu); #endif dprintk(XENLOG_INFO, "VLSAPIC inservice base=%p\n", &VLSAPIC_INSVC(vcpu,0) ); } diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c index f0a3f88cee..7805676502 100644 --- a/xen/arch/x86/hvm/vioapic.c +++ b/xen/arch/x86/hvm/vioapic.c @@ -49,19 +49,6 @@ static int redir_warning_done = 0; #define opt_hvm_debug_level opt_vmx_debug_level #endif -#ifdef HVM_DOMAIN_SAVE_RESTORE -void ioapic_save(QEMUFile* f, void* opaque) -{ - printk("no implementation for ioapic_save\n"); -} - -int ioapic_load(QEMUFile* f, void* opaque, int version_id) -{ - printk("no implementation for ioapic_load\n"); - return 0; -} -#endif - static unsigned long vioapic_read_indirect(struct vioapic *vioapic, unsigned long addr, unsigned long length) @@ -299,19 +286,18 @@ static int ioapic_inj_irq(struct vioapic *vioapic, } #ifndef __ia64__ -static int ioapic_match_logical_addr( - struct vioapic *vioapic, int number, uint8_t dest) +static int vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t dest) { int result = 0; uint32_t logical_dest; - HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_match_logical_addr " - "number %i dest %x\n", - number, dest); + HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "vlapic_match_logical_addr " + "vcpu=%d vlapic_id=%x dest=%x\n", + vlapic_vcpu(vlapic)->vcpu_id, VLAPIC_ID(vlapic), dest); - logical_dest = vlapic_get_reg(vioapic->lapic_info[number], APIC_LDR); + logical_dest = vlapic_get_reg(vlapic, APIC_LDR); - switch ( vlapic_get_reg(vioapic->lapic_info[number], APIC_DFR) ) + switch ( vlapic_get_reg(vlapic, APIC_DFR) ) { case APIC_DFR_FLAT: result = ((dest & GET_APIC_LOGICAL_ID(logical_dest)) != 0); @@ -324,15 +310,15 @@ static int ioapic_match_logical_addr( result = 1; break; default: - gdprintk(XENLOG_WARNING, "error DFR value for %x lapic\n", number); + gdprintk(XENLOG_WARNING, "error DFR value for lapic of vcpu %d\n", + vlapic_vcpu(vlapic)->vcpu_id); break; } return result; } #else -extern int ioapic_match_logical_addr( - struct vioapic *vioapic, int number, uint8_t dest); +extern int vlapic_match_logical_addr(struct vlapic *vlapic, uint16_t dest); #endif static uint32_t ioapic_get_delivery_bitmask(struct vioapic *vioapic, @@ -342,49 +328,40 @@ static uint32_t ioapic_get_delivery_bitmask(struct vioapic *vioapic, uint8_t delivery_mode) { uint32_t mask = 0; - int i; + struct vcpu *v; HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask " - "dest %d dest_mode %d " - "vector %d del_mode %d, lapic_count %d\n", - dest, dest_mode, vector, delivery_mode, vioapic->lapic_count); + "dest %d dest_mode %d vector %d del_mode %d\n", + dest, dest_mode, vector, delivery_mode); - if ( dest_mode == 0 ) + if ( dest_mode == 0 ) /* Physical mode. */ { - /* Physical mode. */ - for ( i = 0; i < vioapic->lapic_count; i++ ) + if ( dest == 0xFF ) /* Broadcast. */ { - if ( VLAPIC_ID(vioapic->lapic_info[i]) == dest ) - { - mask = 1 << i; - break; - } + for_each_vcpu ( vioapic_domain(vioapic), v ) + mask |= 1 << v->vcpu_id; + goto out; } - /* Broadcast. */ - if ( dest == 0xFF ) - { - for ( i = 0; i < vioapic->lapic_count; i++ ) - mask |= ( 1 << i ); - } - } - else - { - /* Logical destination. Call match_logical_addr for each APIC. */ - if ( dest != 0 ) + for_each_vcpu ( vioapic_domain(vioapic), v ) { - for ( i = 0; i < vioapic->lapic_count; i++ ) + if ( VLAPIC_ID(vcpu_vlapic(v)) == dest ) { - if ( vioapic->lapic_info[i] && - ioapic_match_logical_addr(vioapic, i, dest) ) - mask |= (1<<i); + mask = 1 << v->vcpu_id; + break; } } } + else if ( dest != 0 ) /* Logical mode, MDA non-zero. */ + { + for_each_vcpu ( vioapic_domain(vioapic), v ) + if ( vlapic_match_logical_addr(vcpu_vlapic(v), dest) ) + mask |= 1 << v->vcpu_id; + } + out: HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask " "mask %x\n", mask); - return mask; } @@ -397,6 +374,7 @@ static void ioapic_deliver(struct vioapic *vioapic, int irq) uint8_t trig_mode = vioapic->redirtbl[irq].fields.trig_mode; uint32_t deliver_bitmask; struct vlapic *target; + struct vcpu *v; HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "dest=%x dest_mode=%x delivery_mode=%x " @@ -419,7 +397,10 @@ static void ioapic_deliver(struct vioapic *vioapic, int irq) #ifdef IRQ0_SPECIAL_ROUTING /* Force round-robin to pick VCPU 0 */ if ( irq == 0 ) - target = vioapic->lapic_info[0]; + { + v = vioapic_domain(vioapic)->vcpu[0]; + target = v ? vcpu_vlapic(v) : NULL; + } else #endif target = apic_round_robin(vioapic_domain(vioapic), dest_mode, @@ -442,19 +423,21 @@ static void ioapic_deliver(struct vioapic *vioapic, int irq) case dest_ExtINT: { uint8_t bit; - for ( bit = 0; bit < vioapic->lapic_count; bit++ ) + for ( bit = 0; deliver_bitmask != 0; bit++ ) { if ( !(deliver_bitmask & (1 << bit)) ) continue; + deliver_bitmask &= ~(1 << bit); #ifdef IRQ0_SPECIAL_ROUTING /* Do not deliver timer interrupts to VCPU != 0 */ if ( (irq == 0) && (bit != 0) ) - target = vioapic->lapic_info[0]; + v = vioapic_domain(vioapic)->vcpu[0]; else #endif - target = vioapic->lapic_info[bit]; - if ( target != NULL ) + v = vioapic_domain(vioapic)->vcpu[bit]; + if ( v != NULL ) { + target = vcpu_vlapic(v); ioapic_inj_irq(vioapic, target, vector, trig_mode, delivery_mode); vcpu_kick(vlapic_vcpu(target)); @@ -595,26 +578,6 @@ void vioapic_update_EOI(struct domain *d, int vector) } } -int vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v) -{ - struct vioapic *vioapic = domain_vioapic(v->domain); - - if ( v->vcpu_id != vioapic->lapic_count ) - { - gdprintk(XENLOG_ERR, "vioapic_add_lapic " - "cpu_id not match vcpu_id %x lapic_count %x\n", - v->vcpu_id, vioapic->lapic_count); - domain_crash_synchronous(); - } - - /* Update count later for race condition on interrupt. */ - vioapic->lapic_info[vioapic->lapic_count] = vlapic; - wmb(); - vioapic->lapic_count++; - - return vioapic->lapic_count; -} - void vioapic_init(struct domain *d) { struct vioapic *vioapic = domain_vioapic(d); diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c index 31f7d20aab..22888a76c7 100644 --- a/xen/arch/x86/hvm/vlapic.c +++ b/xen/arch/x86/hvm/vlapic.c @@ -1001,8 +1001,6 @@ int vlapic_init(struct vcpu *v) if ( v->vcpu_id == 0 ) vlapic->apic_base_msr |= MSR_IA32_APICBASE_BSP; - vioapic_add_lapic(vlapic, v); - init_timer(&vlapic->vlapic_timer, vlapic_timer_fn, vlapic, v->processor); diff --git a/xen/include/asm-x86/hvm/vioapic.h b/xen/include/asm-x86/hvm/vioapic.h index ad4fb9cd48..32223341ef 100644 --- a/xen/include/asm-x86/hvm/vioapic.h +++ b/xen/include/asm-x86/hvm/vioapic.h @@ -94,19 +94,11 @@ struct vioapic { uint32_t id; unsigned long base_address; union vioapic_redir_entry redirtbl[VIOAPIC_NUM_PINS]; - struct vlapic *lapic_info[32]; - uint32_t lapic_count; }; void vioapic_init(struct domain *d); void vioapic_set_xen_irq(struct domain *d, int irq, int level); void vioapic_set_irq(struct domain *d, int irq, int level); -int vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v); void vioapic_update_EOI(struct domain *d, int vector); -#ifdef HVM_DOMAIN_SAVE_RESTORE -void ioapic_save(QEMUFile* f, void* opaque); -int ioapic_load(QEMUFile* f, void* opaque, int version_id); -#endif - #endif /* __ASM_X86_HVM_VIOAPIC_H__ */ |