diff options
author | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2006-11-10 18:20:49 +0000 |
---|---|---|
committer | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2006-11-10 18:20:49 +0000 |
commit | 8a02f12b77511c9b109abdecd5c10227189d88c8 (patch) | |
tree | 1148e475eb446d7b189129cb279b56efadc97651 | |
parent | 63ffe9b07eed7a2cc7dfc3d02d51c70b29bd389b (diff) | |
download | xen-8a02f12b77511c9b109abdecd5c10227189d88c8.tar.gz xen-8a02f12b77511c9b109abdecd5c10227189d88c8.tar.bz2 xen-8a02f12b77511c9b109abdecd5c10227189d88c8.zip |
[HVM] Simplify apic dest-matching code. Refactor
across vlapic/vioapic source files to reduce code
duplication.
Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r-- | xen/arch/x86/hvm/vioapic.c | 37 | ||||
-rw-r--r-- | xen/arch/x86/hvm/vlapic.c | 94 | ||||
-rw-r--r-- | xen/include/asm-x86/hvm/vlapic.h | 2 |
3 files changed, 45 insertions, 88 deletions
diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c index dc7f29d820..c32ece46e3 100644 --- a/xen/arch/x86/hvm/vioapic.c +++ b/xen/arch/x86/hvm/vioapic.c @@ -35,6 +35,7 @@ #include <public/hvm/ioreq.h> #include <asm/hvm/io.h> #include <asm/hvm/vpic.h> +#include <asm/hvm/vlapic.h> #include <asm/hvm/support.h> #include <asm/current.h> #include <asm/event.h> @@ -285,42 +286,6 @@ static int ioapic_inj_irq(struct vioapic *vioapic, return result; } -#ifndef __ia64__ -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, "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(vlapic, APIC_LDR); - - switch ( vlapic_get_reg(vlapic, APIC_DFR) ) - { - case APIC_DFR_FLAT: - result = ((dest & GET_APIC_LOGICAL_ID(logical_dest)) != 0); - break; - case APIC_DFR_CLUSTER: - /* Should we support flat cluster mode ?*/ - if ( (GET_APIC_LOGICAL_ID(logical_dest) >> 4 - == ((dest >> 0x4) & 0xf)) && - (logical_dest & (dest & 0xf)) ) - result = 1; - break; - default: - gdprintk(XENLOG_WARNING, "error DFR value for lapic of vcpu %d\n", - vlapic_vcpu(vlapic)->vcpu_id); - break; - } - - return result; -} -#else -extern int vlapic_match_logical_addr(struct vlapic *vlapic, uint16_t dest); -#endif - static uint32_t ioapic_get_delivery_bitmask(struct vioapic *vioapic, uint16_t dest, uint8_t dest_mode, diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c index 3209416157..bc8a9736d8 100644 --- a/xen/arch/x86/hvm/vlapic.c +++ b/xen/arch/x86/hvm/vlapic.c @@ -196,63 +196,56 @@ uint32_t vlapic_get_ppr(struct vlapic *vlapic) return ppr; } -/* This only for fixed 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 vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t mda) { int result = 0; - struct vlapic *target = vcpu_vlapic(v); + uint8_t logical_id; - HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "target %p, source %p, dest 0x%x, " - "dest_mode 0x%x, short_hand 0x%x, delivery_mode 0x%x.", - target, source, dest, dest_mode, short_hand, delivery_mode); + logical_id = GET_APIC_LOGICAL_ID(vlapic_get_reg(vlapic, APIC_LDR)); - if ( unlikely(target == NULL) && - ((delivery_mode != APIC_DM_INIT) && - (delivery_mode != APIC_DM_STARTUP) && - (delivery_mode != APIC_DM_NMI)) ) + switch ( vlapic_get_reg(vlapic, APIC_DFR) ) { - HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "uninitialized target vcpu %p, " - "delivery_mode 0x%x, dest 0x%x.\n", - v, delivery_mode, dest); - return result; + case APIC_DFR_FLAT: + if ( logical_id & mda ) + result = 1; + break; + case APIC_DFR_CLUSTER: + if ( ((logical_id >> 4) == (mda >> 0x4)) && (logical_id & mda & 0xf) ) + result = 1; + break; + default: + gdprintk(XENLOG_WARNING, "Bad DFR value for lapic of vcpu %d\n", + vlapic_vcpu(vlapic)->vcpu_id); + break; } + return result; +} + +static int vlapic_match_dest(struct vcpu *v, struct vlapic *source, + int short_hand, int dest, int dest_mode) +{ + int result = 0; + struct vlapic *target = vcpu_vlapic(v); + + HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "target %p, source %p, dest 0x%x, " + "dest_mode 0x%x, short_hand 0x%x\n", + target, source, dest, dest_mode, short_hand); + switch ( short_hand ) { - case APIC_DEST_NOSHORT: /* no shorthand */ - if ( !dest_mode ) /* Physical */ + case APIC_DEST_NOSHORT: + if ( dest_mode == 0 ) { - result = ( ((target != NULL) ? - GET_APIC_ID(vlapic_get_reg(target, APIC_ID)): - v->vcpu_id)) == dest; + /* Physical mode. */ + if ( (dest == 0xFF) || /* broadcast? */ + (GET_APIC_ID(vlapic_get_reg(target, APIC_ID)) == dest) ) + result = 1; } - else /* Logical */ + else { - uint32_t ldr; - if ( target == NULL ) - break; - ldr = vlapic_get_reg(target, APIC_LDR); - - /* Flat mode */ - if ( vlapic_get_reg(target, APIC_DFR) == APIC_DFR_FLAT ) - { - result = GET_APIC_LOGICAL_ID(ldr) & dest; - } - else - { - if ( (delivery_mode == APIC_DM_LOWEST) && - (dest == 0xff) ) - { - /* What shall we do now? */ - gdprintk(XENLOG_ERR, "Broadcast IPI with lowest priority " - "delivery mode\n"); - domain_crash_synchronous(); - } - result = ((GET_APIC_LOGICAL_ID(ldr) == (dest & 0xf)) ? - (GET_APIC_LOGICAL_ID(ldr) >> 4) & (dest >> 4) : 0); - } + /* Logical mode. */ + result = vlapic_match_logical_addr(target, dest); } break; @@ -271,16 +264,14 @@ static int vlapic_match_dest(struct vcpu *v, struct vlapic *source, break; default: + gdprintk(XENLOG_WARNING, "Bad dest shorthand value %x\n", short_hand); break; } return result; } -/* - * Add a pending IRQ into lapic. - * Return 1 if successfully added and 0 if discarded. - */ +/* Add a pending IRQ into lapic. */ static int vlapic_accept_irq(struct vcpu *v, int delivery_mode, int vector, int level, int trig_mode) { @@ -440,10 +431,9 @@ static void vlapic_ipi(struct vlapic *vlapic) for_each_vcpu ( vlapic_domain(vlapic), v ) { - if ( vlapic_match_dest(v, vlapic, short_hand, - dest, dest_mode, delivery_mode) ) + if ( vlapic_match_dest(v, vlapic, short_hand, dest, dest_mode) ) { - if ( delivery_mode == APIC_DM_LOWEST) + if ( delivery_mode == APIC_DM_LOWEST ) set_bit(v->vcpu_id, &lpr_map); else vlapic_accept_irq(v, delivery_mode, diff --git a/xen/include/asm-x86/hvm/vlapic.h b/xen/include/asm-x86/hvm/vlapic.h index c327f5ef3f..807d17e379 100644 --- a/xen/include/asm-x86/hvm/vlapic.h +++ b/xen/include/asm-x86/hvm/vlapic.h @@ -90,4 +90,6 @@ struct vlapic *apic_round_robin( s_time_t get_apictime_scheduled(struct vcpu *v); +int vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t mda); + #endif /* __ASM_X86_HVM_VLAPIC_H__ */ |