[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] hvm: Reduce vpt.c dependencies on external timer details.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1197474080 0 # Node ID 4553bc1087d9f73e5c27f5511c1d4c724b4dbccf # Parent 20898120c8f9b56902ceedb8deaf977175445f2f hvm: Reduce vpt.c dependencies on external timer details. Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/hvm/i8254.c | 2 xen/arch/x86/hvm/irq.c | 25 -------- xen/arch/x86/hvm/rtc.c | 10 --- xen/arch/x86/hvm/vlapic.c | 17 ------ xen/arch/x86/hvm/vpt.c | 110 +++++++++++++++++++++++++-------------- xen/include/asm-x86/hvm/irq.h | 3 - xen/include/asm-x86/hvm/vlapic.h | 3 - xen/include/asm-x86/hvm/vpt.h | 11 ++- 8 files changed, 87 insertions(+), 94 deletions(-) diff -r 20898120c8f9 -r 4553bc1087d9 xen/arch/x86/hvm/i8254.c --- a/xen/arch/x86/hvm/i8254.c Wed Dec 12 12:02:01 2007 +0000 +++ b/xen/arch/x86/hvm/i8254.c Wed Dec 12 15:41:20 2007 +0000 @@ -501,6 +501,8 @@ void pit_init(struct vcpu *v, unsigned l /* Some sub-functions assert that they are called with the lock held. */ spin_lock(&pit->lock); + pit->pt0.source = PTSRC_isa; + register_portio_handler(v->domain, PIT_BASE, 4, handle_pit_io); register_portio_handler(v->domain, 0x61, 1, handle_speaker_io); ticks_per_sec(v) = cpu_khz * (int64_t)1000; diff -r 20898120c8f9 -r 4553bc1087d9 xen/arch/x86/hvm/irq.c --- a/xen/arch/x86/hvm/irq.c Wed Dec 12 12:02:01 2007 +0000 +++ b/xen/arch/x86/hvm/irq.c Wed Dec 12 15:41:20 2007 +0000 @@ -345,31 +345,6 @@ struct hvm_intack hvm_vcpu_ack_pending_i } return intack; -} - -int get_isa_irq_vector(struct vcpu *v, int isa_irq, enum hvm_intsrc src) -{ - unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq); - - if ( src == hvm_intsrc_pic ) - return (v->domain->arch.hvm_domain.vpic[isa_irq >> 3].irq_base - + (isa_irq & 7)); - - ASSERT(src == hvm_intsrc_lapic); - return domain_vioapic(v->domain)->redirtbl[gsi].fields.vector; -} - -int is_isa_irq_masked(struct vcpu *v, int isa_irq) -{ - unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq); - uint8_t pic_imr; - - if ( is_lvtt(v, isa_irq) ) - return !is_lvtt_enabled(v); - - pic_imr = v->domain->arch.hvm_domain.vpic[isa_irq >> 3].imr; - return (((pic_imr & (1 << (isa_irq & 7))) || !vlapic_accept_pic_intr(v)) && - domain_vioapic(v->domain)->redirtbl[gsi].fields.mask); } int hvm_local_events_need_delivery(struct vcpu *v) diff -r 20898120c8f9 -r 4553bc1087d9 xen/arch/x86/hvm/rtc.c --- a/xen/arch/x86/hvm/rtc.c Wed Dec 12 12:02:01 2007 +0000 +++ b/xen/arch/x86/hvm/rtc.c Wed Dec 12 15:41:20 2007 +0000 @@ -40,14 +40,6 @@ static void rtc_periodic_cb(struct vcpu spin_lock(&s->lock); s->hw.cmos_data[RTC_REG_C] |= 0xc0; spin_unlock(&s->lock); -} - -int is_rtc_periodic_irq(void *opaque) -{ - RTCState *s = opaque; - - return !(s->hw.cmos_data[RTC_REG_C] & RTC_AF || - s->hw.cmos_data[RTC_REG_C] & RTC_UF); } /* Enable/configure/disable the periodic timer based on the RTC_PIE and @@ -488,6 +480,8 @@ void rtc_init(struct vcpu *v, int base) spin_lock_init(&s->lock); + s->pt.source = PTSRC_isa; + s->hw.cmos_data[RTC_REG_A] = RTC_REF_CLCK_32KHZ | 6; /* ~1kHz */ s->hw.cmos_data[RTC_REG_B] = RTC_24H; s->hw.cmos_data[RTC_REG_C] = 0; diff -r 20898120c8f9 -r 4553bc1087d9 xen/arch/x86/hvm/vlapic.c --- a/xen/arch/x86/hvm/vlapic.c Wed Dec 12 12:02:01 2007 +0000 +++ b/xen/arch/x86/hvm/vlapic.c Wed Dec 12 15:41:20 2007 +0000 @@ -68,9 +68,6 @@ static unsigned int vlapic_lvt_mask[VLAP #define APIC_DEST_NOSHORT 0x0 #define APIC_DEST_MASK 0x800 -#define vlapic_lvt_enabled(vlapic, lvt_type) \ - (!(vlapic_get_reg(vlapic, lvt_type) & APIC_LVT_MASKED)) - #define vlapic_lvt_vector(vlapic, lvt_type) \ (vlapic_get_reg(vlapic, lvt_type) & APIC_VECTOR_MASK) @@ -932,6 +929,8 @@ int vlapic_init(struct vcpu *v) HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "%d", v->vcpu_id); + vlapic->pt.source = PTSRC_lapic; + #ifdef __i386__ /* 32-bit VMX may be limited to 32-bit physical addresses. */ if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ) @@ -974,15 +973,3 @@ void vlapic_destroy(struct vcpu *v) unmap_domain_page_global(vlapic->regs); free_domheap_page(vlapic->regs_page); } - -int is_lvtt(struct vcpu *v, int vector) -{ - return (pt_active(&vcpu_vlapic(v)->pt) && - (vector == vlapic_lvt_vector(vcpu_vlapic(v), APIC_LVTT))); -} - -int is_lvtt_enabled(struct vcpu *v) -{ - return (vlapic_enabled(vcpu_vlapic(v)) && - vlapic_lvt_enabled(vcpu_vlapic(v), APIC_LVTT)); -} diff -r 20898120c8f9 -r 4553bc1087d9 xen/arch/x86/hvm/vpt.c --- a/xen/arch/x86/hvm/vpt.c Wed Dec 12 12:02:01 2007 +0000 +++ b/xen/arch/x86/hvm/vpt.c Wed Dec 12 15:41:20 2007 +0000 @@ -15,7 +15,6 @@ * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307 USA. - * */ #include <xen/time.h> @@ -25,6 +24,46 @@ #define mode_is(d, name) \ ((d)->arch.hvm_domain.params[HVM_PARAM_TIMER_MODE] == HVMPTM_##name) + +static int pt_irq_vector(struct periodic_time *pt, enum hvm_intsrc src) +{ + struct vcpu *v = pt->vcpu; + unsigned int gsi, isa_irq; + + if ( pt->source == PTSRC_lapic ) + return pt->irq; + + isa_irq = pt->irq; + gsi = hvm_isa_irq_to_gsi(isa_irq); + + if ( src == hvm_intsrc_pic ) + return (v->domain->arch.hvm_domain.vpic[isa_irq >> 3].irq_base + + (isa_irq & 7)); + + ASSERT(src == hvm_intsrc_lapic); + return domain_vioapic(v->domain)->redirtbl[gsi].fields.vector; +} + +static int pt_irq_masked(struct periodic_time *pt) +{ + struct vcpu *v = pt->vcpu; + unsigned int gsi, isa_irq; + uint8_t pic_imr; + + if ( pt->source == PTSRC_lapic ) + { + struct vlapic *vlapic = vcpu_vlapic(v); + return (vlapic_enabled(vlapic) && + !(vlapic_get_reg(vlapic, APIC_LVTT) & APIC_LVT_MASKED)); + } + + isa_irq = pt->irq; + gsi = hvm_isa_irq_to_gsi(isa_irq); + pic_imr = v->domain->arch.hvm_domain.vpic[isa_irq >> 3].imr; + + return (((pic_imr & (1 << (isa_irq & 7))) || !vlapic_accept_pic_intr(v)) && + domain_vioapic(v->domain)->redirtbl[gsi].fields.mask); +} static void pt_lock(struct periodic_time *pt) { @@ -144,29 +183,39 @@ void pt_update_irq(struct vcpu *v) void pt_update_irq(struct vcpu *v) { struct list_head *head = &v->arch.hvm_vcpu.tm_list; - struct periodic_time *pt; + struct periodic_time *pt, *earliest_pt = NULL; uint64_t max_lag = -1ULL; - int irq = -1; - - spin_lock(&v->arch.hvm_vcpu.tm_lock); - - list_for_each_entry ( pt, head, list ) - { - if ( !is_isa_irq_masked(v, pt->irq) && pt->pending_intr_nr && + int irq, is_lapic; + + spin_lock(&v->arch.hvm_vcpu.tm_lock); + + list_for_each_entry ( pt, head, list ) + { + if ( !pt_irq_masked(pt) && pt->pending_intr_nr && ((pt->last_plt_gtime + pt->period_cycles) < max_lag) ) { max_lag = pt->last_plt_gtime + pt->period_cycles; - irq = pt->irq; + earliest_pt = pt; } } - spin_unlock(&v->arch.hvm_vcpu.tm_lock); - - if ( is_lvtt(v, irq) ) + if ( earliest_pt == NULL ) + { + spin_unlock(&v->arch.hvm_vcpu.tm_lock); + return; + } + + earliest_pt->irq_issued = 1; + irq = earliest_pt->irq; + is_lapic = (earliest_pt->source == PTSRC_lapic); + + spin_unlock(&v->arch.hvm_vcpu.tm_lock); + + if ( is_lapic ) { vlapic_set_irq(vcpu_vlapic(v), irq, 0); } - else if ( irq >= 0 ) + else { hvm_isa_irq_deassert(v->domain, irq); hvm_isa_irq_assert(v->domain, irq); @@ -178,29 +227,12 @@ static struct periodic_time *is_pt_irq( { struct list_head *head = &v->arch.hvm_vcpu.tm_list; struct periodic_time *pt; - struct RTCState *rtc = &v->domain->arch.hvm_domain.pl_time.vrtc; - int vector; - - list_for_each_entry ( pt, head, list ) - { - if ( !pt->pending_intr_nr ) - continue; - - if ( is_lvtt(v, pt->irq) ) - { - if ( pt->irq != intack.vector ) - continue; + + list_for_each_entry ( pt, head, list ) + { + if ( pt->pending_intr_nr && pt->irq_issued && + (intack.vector == pt_irq_vector(pt, intack.source)) ) return pt; - } - - vector = get_isa_irq_vector(v, pt->irq, intack.source); - - /* RTC irq need special care */ - if ( (intack.vector != vector) || - ((pt->irq == 8) && !is_rtc_periodic_irq(rtc)) ) - continue; - - return pt; } return NULL; @@ -222,6 +254,7 @@ void pt_intr_post(struct vcpu *v, struct } pt->do_not_freeze = 0; + pt->irq_issued = 0; if ( pt->one_shot ) { @@ -291,12 +324,15 @@ void create_periodic_time( struct vcpu *v, struct periodic_time *pt, uint64_t period, uint8_t irq, char one_shot, time_cb *cb, void *data) { + ASSERT(pt->source != 0); + destroy_periodic_time(pt); spin_lock(&v->arch.hvm_vcpu.tm_lock); pt->pending_intr_nr = 0; pt->do_not_freeze = 0; + pt->irq_issued = 0; /* Periodic timer must be at least 0.9ms. */ if ( (period < 900000) && !one_shot ) @@ -319,7 +355,7 @@ void create_periodic_time( * LAPIC ticks for process accounting can see long sequences of process * ticks incorrectly accounted to interrupt processing. */ - if ( is_lvtt(v, irq) ) + if ( pt->source == PTSRC_lapic ) pt->scheduled += period >> 1; pt->cb = cb; pt->priv = data; diff -r 20898120c8f9 -r 4553bc1087d9 xen/include/asm-x86/hvm/irq.h --- a/xen/include/asm-x86/hvm/irq.h Wed Dec 12 12:02:01 2007 +0000 +++ b/xen/include/asm-x86/hvm/irq.h Wed Dec 12 15:41:20 2007 +0000 @@ -160,7 +160,4 @@ struct hvm_intack hvm_vcpu_ack_pending_i struct hvm_intack hvm_vcpu_ack_pending_irq(struct vcpu *v, struct hvm_intack intack); -int get_isa_irq_vector(struct vcpu *vcpu, int irq, enum hvm_intsrc src); -int is_isa_irq_masked(struct vcpu *v, int isa_irq); - #endif /* __ASM_X86_HVM_IRQ_H__ */ diff -r 20898120c8f9 -r 4553bc1087d9 xen/include/asm-x86/hvm/vlapic.h --- a/xen/include/asm-x86/hvm/vlapic.h Wed Dec 12 12:02:01 2007 +0000 +++ b/xen/include/asm-x86/hvm/vlapic.h Wed Dec 12 15:41:20 2007 +0000 @@ -92,7 +92,4 @@ struct vlapic *apic_round_robin( int vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t mda); -int is_lvtt(struct vcpu *v, int vector); -int is_lvtt_enabled(struct vcpu *v); - #endif /* __ASM_X86_HVM_VLAPIC_H__ */ diff -r 20898120c8f9 -r 4553bc1087d9 xen/include/asm-x86/hvm/vpt.h --- a/xen/include/asm-x86/hvm/vpt.h Wed Dec 12 12:02:01 2007 +0000 +++ b/xen/include/asm-x86/hvm/vpt.h Wed Dec 12 15:41:20 2007 +0000 @@ -75,6 +75,10 @@ struct periodic_time { bool_t on_list; bool_t one_shot; bool_t do_not_freeze; + bool_t irq_issued; +#define PTSRC_isa 1 /* ISA time source */ +#define PTSRC_lapic 2 /* LAPIC time source */ + u8 source; /* PTSRC_ */ u8 irq; struct vcpu *vcpu; /* vcpu timer interrupt delivers to */ u32 pending_intr_nr; /* pending timer interrupts */ @@ -146,8 +150,10 @@ void pt_migrate(struct vcpu *v); /* * Create/destroy a periodic (or one-shot!) timer. - * The given periodic timer structure must be initialised with zero bytes or - * have been initialised by a previous invocation of create_periodic_time(). + * The given periodic timer structure must be initialised with zero bytes, + * except for the 'source' field which must be initialised with the + * correct PTSRC_ value. The initialised timer structure can then be passed + * to {create,destroy}_periodic_time() and number of times and in any order. * Note that, for a given periodic timer, invocations of these functions MUST * be serialised. */ @@ -163,7 +169,6 @@ void rtc_init(struct vcpu *v, int base); void rtc_init(struct vcpu *v, int base); void rtc_migrate_timers(struct vcpu *v); void rtc_deinit(struct domain *d); -int is_rtc_periodic_irq(void *opaque); void pmtimer_init(struct vcpu *v); void pmtimer_deinit(struct domain *d); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |