[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [HVM] VIOAPIC and VPIC cleanups.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID cba947bc845063ed820142bb921121ab8ead6452 # Parent 9fbb26d47b8397681de6c910540f4ab0835ca787 [HVM] VIOAPIC and VPIC cleanups. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/ia64/vmx/vlsapic.c | 8 xen/arch/ia64/vmx/vmx_init.c | 2 xen/arch/x86/hvm/hvm.c | 12 xen/arch/x86/hvm/i8259.c | 154 +++--- xen/arch/x86/hvm/rtc.c | 22 xen/arch/x86/hvm/svm/intr.c | 2 xen/arch/x86/hvm/vioapic.c | 861 +++++++++++++++++------------------- xen/arch/x86/hvm/vlapic.c | 4 xen/arch/x86/hvm/vmx/io.c | 2 xen/include/asm-ia64/vmx_platform.h | 2 xen/include/asm-x86/hvm/domain.h | 4 xen/include/asm-x86/hvm/vioapic.h | 111 ++-- xen/include/asm-x86/hvm/vpic.h | 32 - 13 files changed, 588 insertions(+), 628 deletions(-) diff -r 9fbb26d47b83 -r cba947bc8450 xen/arch/ia64/vmx/vlsapic.c --- a/xen/arch/ia64/vmx/vlsapic.c Tue Nov 07 15:48:10 2006 +0000 +++ b/xen/arch/ia64/vmx/vlsapic.c Tue Nov 07 17:46:40 2006 +0000 @@ -324,7 +324,7 @@ void vtm_domain_in(VCPU *vcpu) */ #ifdef V_IOSAPIC_READY -int ioapic_match_logical_addr(hvm_vioapic_t *s, int number, uint16_t dest) +int ioapic_match_logical_addr(struct vioapic *s, int number, uint16_t dest) { return (VLAPIC_ID(s->lapic_info[number]) == dest); } @@ -335,14 +335,14 @@ struct vlapic* apic_round_robin(struct d uint32_t bitmap) { uint8_t bit; - hvm_vioapic_t *s; + struct vioapic *s; if (!bitmap) { printk("<apic_round_robin> no bit on bitmap\n"); return NULL; } - s = &d->arch.vmx_platform.vioapic; + s = domain_vioapic(d); for (bit = 0; bit < s->lapic_count; bit++) { if (bitmap & (1 << bit)) return s->lapic_info[bit]; @@ -375,7 +375,7 @@ void vlsapic_reset(VCPU *vcpu) #ifdef V_IOSAPIC_READY vcpu->arch.arch_vmx.vlapic.vcpu = vcpu; - hvm_vioapic_add_lapic(&vcpu->arch.arch_vmx.vlapic, vcpu); + vioapic_add_lapic(&vcpu->arch.arch_vmx.vlapic, vcpu); #endif dprintk(XENLOG_INFO, "VLSAPIC inservice base=%p\n", &VLSAPIC_INSVC(vcpu,0) ); } diff -r 9fbb26d47b83 -r cba947bc8450 xen/arch/ia64/vmx/vmx_init.c --- a/xen/arch/ia64/vmx/vmx_init.c Tue Nov 07 15:48:10 2006 +0000 +++ b/xen/arch/ia64/vmx/vmx_init.c Tue Nov 07 17:46:40 2006 +0000 @@ -456,7 +456,7 @@ void vmx_setup_platform(struct domain *d spin_lock_init(&d->arch.arch_vmx.virq_assist_lock); /* Initialize iosapic model within hypervisor */ - hvm_vioapic_init(d); + vioapic_init(d); } void vmx_do_launch(struct vcpu *v) diff -r 9fbb26d47b83 -r cba947bc8450 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Tue Nov 07 15:48:10 2006 +0000 +++ b/xen/arch/x86/hvm/hvm.c Tue Nov 07 17:46:40 2006 +0000 @@ -133,7 +133,7 @@ int hvm_domain_initialise(struct domain pic_init(&platform->vpic, pic_irq_request, &platform->interrupt_request); register_pic_io_hook(d); - hvm_vioapic_init(d); + vioapic_init(d); return 0; } @@ -219,15 +219,15 @@ int cpu_get_interrupt(struct vcpu *v, in int cpu_get_interrupt(struct vcpu *v, int *type) { int intno; - struct hvm_virpic *s = &v->domain->arch.hvm_domain.vpic; + struct vpic *vpic = domain_vpic(v->domain); unsigned long flags; if ( (intno = cpu_get_apic_interrupt(v, type)) != -1 ) { /* set irq request if a PIC irq is still pending */ /* XXX: improve that */ - spin_lock_irqsave(&s->lock, flags); - pic_update_irq(s); - spin_unlock_irqrestore(&s->lock, flags); + spin_lock_irqsave(&vpic->lock, flags); + pic_update_irq(vpic); + spin_unlock_irqrestore(&vpic->lock, flags); return intno; } /* read the irq from the PIC */ @@ -674,7 +674,7 @@ long do_hvm_op(unsigned long op, XEN_GUE rc = -EINVAL; if ( is_hvm_domain(d) ) { - pic_set_irq(&d->arch.hvm_domain.vpic, op.irq, op.level); + pic_set_irq(domain_vpic(d), op.irq, op.level); rc = 0; } diff -r 9fbb26d47b83 -r cba947bc8450 xen/arch/x86/hvm/i8259.c --- a/xen/arch/x86/hvm/i8259.c Tue Nov 07 15:48:10 2006 +0000 +++ b/xen/arch/x86/hvm/i8259.c Tue Nov 07 17:46:40 2006 +0000 @@ -5,10 +5,10 @@ * Copyright (c) 2005 Intel Corperation * * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in @@ -18,10 +18,11 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. */ + #include <xen/config.h> #include <xen/types.h> #include <xen/mm.h> @@ -33,6 +34,8 @@ #include <asm/hvm/io.h> #include <asm/hvm/support.h> #include <asm/current.h> + +#define hw_error(x) ((void)0) /* set irq level. If an edge is detected, then the IRR is set to 1 */ static inline void pic_set_irq1(PicState *s, int irq, int level) @@ -108,38 +111,38 @@ static int pic_get_irq(PicState *s) /* raise irq to CPU if necessary. must be called every time the active irq may change */ /* XXX: should not export it, but it is needed for an APIC kludge */ -void pic_update_irq(struct hvm_virpic *s) +void pic_update_irq(struct vpic *vpic) { int irq2, irq; - ASSERT(spin_is_locked(&s->lock)); + ASSERT(spin_is_locked(&vpic->lock)); /* first look at slave pic */ - irq2 = pic_get_irq(&s->pics[1]); + irq2 = pic_get_irq(&vpic->pics[1]); if (irq2 >= 0) { /* if irq request by slave pic, signal master PIC */ - pic_set_irq1(&s->pics[0], 2, 1); - pic_set_irq1(&s->pics[0], 2, 0); + pic_set_irq1(&vpic->pics[0], 2, 1); + pic_set_irq1(&vpic->pics[0], 2, 0); } /* look at requested irq */ - irq = pic_get_irq(&s->pics[0]); + irq = pic_get_irq(&vpic->pics[0]); if (irq >= 0) { - s->irq_request(s->irq_request_opaque, 1); + vpic->irq_request(vpic->irq_request_opaque, 1); } } void pic_set_xen_irq(void *opaque, int irq, int level) { - struct hvm_virpic *s = opaque; + struct vpic *vpic = opaque; unsigned long flags; PicState *ps; - spin_lock_irqsave(&s->lock, flags); - - hvm_vioapic_set_xen_irq(current->domain, irq, level); + spin_lock_irqsave(&vpic->lock, flags); + + vioapic_set_xen_irq(current->domain, irq, level); /* Set it on the 8259s */ - ps = &s->pics[irq >> 3]; + ps = &vpic->pics[irq >> 3]; if (!(ps->elcr & (1 << (irq & 7)))) gdprintk(XENLOG_WARNING, "edge-triggered override IRQ?\n"); if (level) { @@ -148,26 +151,25 @@ void pic_set_xen_irq(void *opaque, int i ps->irr_xen &= ~(1 << (irq & 7)); } - pic_update_irq(s); - spin_unlock_irqrestore(&s->lock, flags); -} - -void pic_set_irq(struct hvm_virpic *s, int irq, int level) + pic_update_irq(vpic); + spin_unlock_irqrestore(&vpic->lock, flags); +} + +void pic_set_irq(struct vpic *vpic, int irq, int level) { unsigned long flags; if ( irq < 0 ) return; - spin_lock_irqsave(&s->lock, flags); - hvm_vioapic_set_irq(container_of(s, struct domain, arch.hvm_domain.vpic), - irq, level); + spin_lock_irqsave(&vpic->lock, flags); + vioapic_set_irq(vpic_domain(vpic), irq, level); if ( irq < 16 ) { - pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); - pic_update_irq(s); - } - spin_unlock_irqrestore(&s->lock, flags); + pic_set_irq1(&vpic->pics[irq >> 3], irq & 7, level); + pic_update_irq(vpic); + } + spin_unlock_irqrestore(&vpic->lock, flags); } /* acknowledge interrupt 'irq' */ @@ -186,37 +188,37 @@ static inline void pic_intack(PicState * s->irr &= ~(1 << irq); } -static int pic_read_irq(struct hvm_virpic *s) +static int pic_read_irq(struct vpic *vpic) { int irq, irq2, intno; unsigned long flags; - spin_lock_irqsave(&s->lock, flags); - irq = pic_get_irq(&s->pics[0]); + spin_lock_irqsave(&vpic->lock, flags); + irq = pic_get_irq(&vpic->pics[0]); if (irq >= 0) { - pic_intack(&s->pics[0], irq); + pic_intack(&vpic->pics[0], irq); if (irq == 2) { - irq2 = pic_get_irq(&s->pics[1]); + irq2 = pic_get_irq(&vpic->pics[1]); if (irq2 >= 0) { - pic_intack(&s->pics[1], irq2); + pic_intack(&vpic->pics[1], irq2); } else { /* spurious IRQ on slave controller */ gdprintk(XENLOG_WARNING, "Spurious irq on slave i8259.\n"); irq2 = 7; } - intno = s->pics[1].irq_base + irq2; + intno = vpic->pics[1].irq_base + irq2; irq = irq2 + 8; } else { - intno = s->pics[0].irq_base + irq; + intno = vpic->pics[0].irq_base + irq; } } else { /* spurious IRQ on host controller */ irq = 7; - intno = s->pics[0].irq_base + irq; + intno = vpic->pics[0].irq_base + irq; gdprintk(XENLOG_WARNING, "Spurious irq on master i8259.\n"); } - pic_update_irq(s); - spin_unlock_irqrestore(&s->lock, flags); + pic_update_irq(vpic); + spin_unlock_irqrestore(&vpic->lock, flags); return intno; } @@ -414,28 +416,28 @@ static void pic_init1(int io_addr, int e s->elcr = 0xff & s->elcr_mask; } -void pic_init(struct hvm_virpic *s, void (*irq_request)(void *, int), +void pic_init(struct vpic *vpic, void (*irq_request)(void *, int), void *irq_request_opaque) { unsigned long flags; - memset(s, 0, sizeof(*s)); - spin_lock_init(&s->lock); - s->pics[0].pics_state = s; - s->pics[1].pics_state = s; - s->pics[0].elcr_mask = 0xf8; - s->pics[1].elcr_mask = 0xde; - spin_lock_irqsave(&s->lock, flags); - pic_init1(0x20, 0x4d0, &s->pics[0]); - pic_init1(0xa0, 0x4d1, &s->pics[1]); - spin_unlock_irqrestore(&s->lock, flags); - s->irq_request = irq_request; - s->irq_request_opaque = irq_request_opaque; + memset(vpic, 0, sizeof(*vpic)); + spin_lock_init(&vpic->lock); + vpic->pics[0].pics_state = vpic; + vpic->pics[1].pics_state = vpic; + vpic->pics[0].elcr_mask = 0xf8; + vpic->pics[1].elcr_mask = 0xde; + spin_lock_irqsave(&vpic->lock, flags); + pic_init1(0x20, 0x4d0, &vpic->pics[0]); + pic_init1(0xa0, 0x4d1, &vpic->pics[1]); + spin_unlock_irqrestore(&vpic->lock, flags); + vpic->irq_request = irq_request; + vpic->irq_request_opaque = irq_request_opaque; } static int intercept_pic_io(ioreq_t *p) { - struct hvm_virpic *pic; + struct vpic *pic; uint32_t data; unsigned long flags; @@ -444,7 +446,7 @@ static int intercept_pic_io(ioreq_t *p) return 1; } - pic = ¤t->domain->arch.hvm_domain.vpic; + pic = domain_vpic(current->domain); if ( p->dir == IOREQ_WRITE ) { if ( p->data_is_ptr ) (void)hvm_copy_from_guest_phys(&data, p->data, p->size); @@ -470,7 +472,7 @@ static int intercept_pic_io(ioreq_t *p) static int intercept_elcr_io(ioreq_t *p) { - struct hvm_virpic *s; + struct vpic *vpic; uint32_t data; unsigned long flags; @@ -479,20 +481,20 @@ static int intercept_elcr_io(ioreq_t *p) return 1; } - s = ¤t->domain->arch.hvm_domain.vpic; + vpic = domain_vpic(current->domain); if ( p->dir == IOREQ_WRITE ) { if ( p->data_is_ptr ) (void)hvm_copy_from_guest_phys(&data, p->data, p->size); else data = p->data; - spin_lock_irqsave(&s->lock, flags); - elcr_ioport_write((void*)&s->pics[p->addr&1], + spin_lock_irqsave(&vpic->lock, flags); + elcr_ioport_write((void*)&vpic->pics[p->addr&1], (uint32_t) p->addr, (uint32_t)( data & 0xff)); - spin_unlock_irqrestore(&s->lock, flags); + spin_unlock_irqrestore(&vpic->lock, flags); } else { data = (u64) elcr_ioport_read( - (void*)&s->pics[p->addr&1], (uint32_t) p->addr); + (void*)&vpic->pics[p->addr&1], (uint32_t) p->addr); if ( p->data_is_ptr ) (void)hvm_copy_to_guest_phys(p->data, &data, p->size); else @@ -514,7 +516,7 @@ int cpu_get_pic_interrupt(struct vcpu *v int cpu_get_pic_interrupt(struct vcpu *v, int *type) { int intno; - struct hvm_virpic *s = &v->domain->arch.hvm_domain.vpic; + struct vpic *vpic = domain_vpic(v->domain); struct hvm_domain *plat = &v->domain->arch.hvm_domain; if ( !vlapic_accept_pic_intr(v) ) @@ -524,7 +526,7 @@ int cpu_get_pic_interrupt(struct vcpu *v return -1; /* read the irq from the PIC */ - intno = pic_read_irq(s); + intno = pic_read_irq(vpic); *type = APIC_DM_EXTINT; return intno; } @@ -539,10 +541,9 @@ int is_periodic_irq(struct vcpu *v, int if (pt->irq == 0) { /* Is it pit irq? */ if (type == APIC_DM_EXTINT) - vec = v->domain->arch.hvm_domain.vpic.pics[0].irq_base; - else - vec = - v->domain->arch.hvm_domain.vioapic.redirtbl[0].RedirForm.vector; + vec = domain_vpic(v->domain)->pics[0].irq_base; + else + vec = domain_vioapic(v->domain)->redirtbl[0].fields.vector; if (irq == vec) return 1; @@ -550,10 +551,9 @@ int is_periodic_irq(struct vcpu *v, int if (pt->irq == 8) { /* Or rtc irq? */ if (type == APIC_DM_EXTINT) - vec = v->domain->arch.hvm_domain.vpic.pics[1].irq_base; - else - vec = - v->domain->arch.hvm_domain.vioapic.redirtbl[8].RedirForm.vector; + vec = domain_vpic(v->domain)->pics[1].irq_base; + else + vec = domain_vioapic(v->domain)->redirtbl[8].fields.vector; if (irq == vec) return is_rtc_periodic_irq(vrtc); @@ -564,10 +564,10 @@ int is_periodic_irq(struct vcpu *v, int int is_irq_enabled(struct vcpu *v, int irq) { - struct hvm_vioapic *vioapic = &v->domain->arch.hvm_domain.vioapic; - struct hvm_virpic *vpic=&v->domain->arch.hvm_domain.vpic; - - if (vioapic->redirtbl[irq].RedirForm.mask == 0) + struct vioapic *vioapic = domain_vioapic(v->domain); + struct vpic *vpic = domain_vpic(v->domain); + + if (vioapic->redirtbl[irq].fields.mask == 0) return 1; if ( irq & 8 ) { diff -r 9fbb26d47b83 -r cba947bc8450 xen/arch/x86/hvm/rtc.c --- a/xen/arch/x86/hvm/rtc.c Tue Nov 07 15:48:10 2006 +0000 +++ b/xen/arch/x86/hvm/rtc.c Tue Nov 07 17:46:40 2006 +0000 @@ -4,10 +4,10 @@ * Copyright (c) 2003-2004 Fabrice Bellard * * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in @@ -17,9 +17,9 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. */ #include <asm/mc146818rtc.h> @@ -263,8 +263,8 @@ static void rtc_update_second2(void *opa static void rtc_update_second2(void *opaque) { RTCState *s = opaque; - struct hvm_domain *plat=&s->vcpu->domain->arch.hvm_domain; - struct hvm_virpic *pic= &plat->vpic; + struct hvm_domain *plat = &s->vcpu->domain->arch.hvm_domain; + struct vpic *pic = &plat->vpic; if (!(s->cmos_data[RTC_REG_B] & RTC_SET)) { rtc_copy_date(s); @@ -302,8 +302,8 @@ static uint32_t rtc_ioport_read(void *op static uint32_t rtc_ioport_read(void *opaque, uint32_t addr) { RTCState *s = opaque; - struct hvm_domain *plat=&s->vcpu->domain->arch.hvm_domain; - struct hvm_virpic *pic= &plat->vpic; + struct hvm_domain *plat = &s->vcpu->domain->arch.hvm_domain; + struct vpic *pic = &plat->vpic; int ret; if ((addr & 1) == 0) { diff -r 9fbb26d47b83 -r cba947bc8450 xen/arch/x86/hvm/svm/intr.c --- a/xen/arch/x86/hvm/svm/intr.c Tue Nov 07 15:48:10 2006 +0000 +++ b/xen/arch/x86/hvm/svm/intr.c Tue Nov 07 17:46:40 2006 +0000 @@ -65,7 +65,7 @@ asmlinkage void svm_intr_assist(void) struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; struct hvm_domain *plat=&v->domain->arch.hvm_domain; struct periodic_time *pt = &plat->pl_time.periodic_tm; - struct hvm_virpic *pic= &plat->vpic; + struct vpic *pic= &plat->vpic; int callback_irq; int intr_type = APIC_DM_EXTINT; int intr_vector = -1; diff -r 9fbb26d47b83 -r cba947bc8450 xen/arch/x86/hvm/vioapic.c --- a/xen/arch/x86/hvm/vioapic.c Tue Nov 07 15:48:10 2006 +0000 +++ b/xen/arch/x86/hvm/vioapic.c Tue Nov 07 17:46:40 2006 +0000 @@ -1,31 +1,29 @@ /* -* Copyright (C) 2001 MandrakeSoft S.A. -* -* MandrakeSoft S.A. -* 43, rue d'Aboukir -* 75002 Paris - France -* http://www.linux-mandrake.com/ -* http://www.mandrakesoft.com/ -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; either -* version 2 of the License, or (at your option) any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* -* Yunhong Jiang <yunhong.jiang@xxxxxxxxx> -* Ported to xen by using virtual IRQ line. -*/ + * Copyright (C) 2001 MandrakeSoft S.A. + * + * MandrakeSoft S.A. + * 43, rue d'Aboukir + * 75002 Paris - France + * http://www.linux-mandrake.com/ + * http://www.mandrakesoft.com/ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Yunhong Jiang <yunhong.jiang@xxxxxxxxx> + * Ported to xen by using virtual IRQ line. + */ #include <xen/config.h> #include <xen/types.h> @@ -51,14 +49,6 @@ static int redir_warning_done = 0; #define opt_hvm_debug_level opt_vmx_debug_level #endif -static void ioapic_enable(hvm_vioapic_t *s, uint8_t enable) -{ - if (enable) - s->flags |= IOAPIC_ENABLE_FLAG; - else - s->flags &= ~IOAPIC_ENABLE_FLAG; -} - #ifdef HVM_DOMAIN_SAVE_RESTORE void ioapic_save(QEMUFile* f, void* opaque) { @@ -72,234 +62,215 @@ int ioapic_load(QEMUFile* f, void* opaqu } #endif -static unsigned long hvm_vioapic_read_indirect(struct hvm_vioapic *s, - unsigned long addr, - unsigned long length) +static unsigned long vioapic_read_indirect(struct vioapic *vioapic, + unsigned long addr, + unsigned long length) { unsigned long result = 0; - ASSERT(s); - - switch (s->ioregsel) { - case IOAPIC_REG_VERSION: - result = ((((IOAPIC_NUM_PINS-1) & 0xff) << 16) - | (IOAPIC_VERSION_ID & 0xff)); - break; - -#ifndef __ia64__ - case IOAPIC_REG_APIC_ID: - result = ((s->id & 0xf) << 24); - break; - - case IOAPIC_REG_ARB_ID: - /* XXX how arb_id used on p4? */ - result = ((s->arb_id & 0xf) << 24); - break; -#endif - - default: - { - uint32_t redir_index = 0; - uint64_t redir_content = 0; - - redir_index = (s->ioregsel - 0x10) >> 1; - - if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS) { - redir_content = s->redirtbl[redir_index].value; - - result = (s->ioregsel & 0x1)? - (redir_content >> 32) & 0xffffffff : - redir_content & 0xffffffff; - } else { - printk("apic_mem_readl:undefined ioregsel %x\n", - s->ioregsel); - domain_crash_synchronous(); + switch ( vioapic->ioregsel ) + { + case VIOAPIC_REG_VERSION: + result = ((((VIOAPIC_NUM_PINS-1) & 0xff) << 16) + | (VIOAPIC_VERSION_ID & 0xff)); + break; + +#if !VIOAPIC_IS_IOSAPIC + case VIOAPIC_REG_APIC_ID: + case VIOAPIC_REG_ARB_ID: + result = ((vioapic->id & 0xf) << 24); + break; +#endif + + default: + { + uint32_t redir_index = (vioapic->ioregsel - 0x10) >> 1; + uint64_t redir_content; + + if ( redir_index >= VIOAPIC_NUM_PINS ) + { + gdprintk(XENLOG_WARNING, "apic_mem_readl:undefined ioregsel %x\n", + vioapic->ioregsel); + break; + } + + redir_content = vioapic->redirtbl[redir_index].bits; + result = (vioapic->ioregsel & 0x1)? + (redir_content >> 32) & 0xffffffff : + redir_content & 0xffffffff; + break; + } + } + + return result; +} + +static unsigned long vioapic_read(struct vcpu *v, + unsigned long addr, + unsigned long length) +{ + struct vioapic *vioapic = domain_vioapic(v->domain); + uint32_t result; + + HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "vioapic_read addr %lx\n", addr); + + addr &= 0xff; + + switch ( addr ) + { + case VIOAPIC_REG_SELECT: + result = vioapic->ioregsel; + break; + + case VIOAPIC_REG_WINDOW: + result = vioapic_read_indirect(vioapic, addr, length); + break; + + default: + result = 0; + break; + } + + return result; +} + +static void vioapic_update_imr(struct vioapic *vioapic, int index) +{ + if ( vioapic->redirtbl[index].fields.mask ) + set_bit(index, &vioapic->imr); + else + clear_bit(index, &vioapic->imr); +} + + +static void vioapic_write_indirect(struct vioapic *vioapic, + unsigned long addr, + unsigned long length, + unsigned long val) +{ + switch ( vioapic->ioregsel ) + { + case VIOAPIC_REG_VERSION: + /* Writes are ignored. */ + break; + +#if !VIOAPIC_IS_IOSAPIC + case VIOAPIC_REG_APIC_ID: + vioapic->id = (val >> 24) & 0xf; + break; + + case VIOAPIC_REG_ARB_ID: + break; +#endif + + default: + { + uint32_t redir_index = (vioapic->ioregsel - 0x10) >> 1; + uint64_t redir_content; + + HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "vioapic_write_indirect " + "change redir index %x val %lx\n", + redir_index, val); + + if ( redir_index >= VIOAPIC_NUM_PINS ) + { + gdprintk(XENLOG_WARNING, "vioapic_write_indirect " + "error register %x\n", vioapic->ioregsel); + break; + } + + redir_content = vioapic->redirtbl[redir_index].bits; + + if ( vioapic->ioregsel & 0x1 ) + { +#ifdef IRQ0_SPECIAL_ROUTING + if ( !redir_warning_done && (redir_index == 0) && + ((val >> 24) != 0) ) + { + /* + * Cannot yet handle delivering PIT interrupts to any VCPU != + * 0. Needs proper fixing, but for now simply spit a warning + * that we're going to ignore the target in practice and always + * deliver to VCPU 0. + */ + printk("IO-APIC: PIT (IRQ0) redirect to VCPU %lx " + "will be ignored.\n", val >> 24); + redir_warning_done = 1; } - break; - } +#endif + redir_content = (((uint64_t)val & 0xffffffff) << 32) | + (redir_content & 0xffffffff); + } + else + { + redir_content = ((redir_content >> 32) << 32) | + (val & 0xffffffff); + } + vioapic->redirtbl[redir_index].bits = redir_content; + vioapic_update_imr(vioapic, redir_index); + break; + } } /* switch */ - - return result; -} - -static unsigned long hvm_vioapic_read(struct vcpu *v, - unsigned long addr, - unsigned long length) -{ - struct hvm_vioapic *s = &(v->domain->arch.hvm_domain.vioapic); - uint32_t result = 0; - - HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "hvm_vioapic_read addr %lx\n", addr); - - ASSERT(s); +} + +static void vioapic_write(struct vcpu *v, + unsigned long addr, + unsigned long length, + unsigned long val) +{ + struct vioapic *vioapic = domain_vioapic(v->domain); addr &= 0xff; - switch (addr) { - case IOAPIC_REG_SELECT: - result = s->ioregsel; - break; - - case IOAPIC_REG_WINDOW: - result = hvm_vioapic_read_indirect(s, addr, length); - break; - - default: - break; - } - - return result; -} - -static void hvm_vioapic_update_imr(struct hvm_vioapic *s, int index) -{ - if (s->redirtbl[index].RedirForm.mask) - set_bit(index, &s->imr); - else - clear_bit(index, &s->imr); -} - - -static void hvm_vioapic_write_indirect(struct hvm_vioapic *s, - unsigned long addr, - unsigned long length, - unsigned long val) -{ - switch (s->ioregsel) { - case IOAPIC_REG_VERSION: - printk("hvm_vioapic_write_indirect: version register read only\n"); - break; - -#ifndef __ia64__ - case IOAPIC_REG_APIC_ID: - s->id = (val >> 24) & 0xf; - break; - - case IOAPIC_REG_ARB_ID: - s->arb_id = val; - break; -#endif - - default: - { - uint32_t redir_index = 0; - - redir_index = (s->ioregsel - 0x10) >> 1; - - HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "hvm_vioapic_write_indirect " - "change redir index %x val %lx\n", - redir_index, val); - - if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS) { - uint64_t redir_content; - - redir_content = s->redirtbl[redir_index].value; - - if (s->ioregsel & 0x1) { -#ifdef IRQ0_SPECIAL_ROUTING - if ( !redir_warning_done && (redir_index == 0) && - ((val >> 24) != 0) ) { - /* - * Cannot yet handle delivering PIT interrupts to - * any VCPU != 0. Needs proper fixing, but for now - * simply spit a warning that we're going to ignore - * the target in practice & always deliver to VCPU 0 - */ - printk("IO-APIC: PIT (IRQ0) redirect to VCPU %lx " - "will be ignored.\n", val >> 24); - redir_warning_done = 1; - } -#endif - redir_content = (((uint64_t)val & 0xffffffff) << 32) | - (redir_content & 0xffffffff); - } else - redir_content = ((redir_content >> 32) << 32) | - (val & 0xffffffff); - s->redirtbl[redir_index].value = redir_content; - hvm_vioapic_update_imr(s, redir_index); - } else { - printk("hvm_vioapic_write_indirect " - "error register %x\n", s->ioregsel); - } - break; - } - } /* switch */ -} - -static void hvm_vioapic_write(struct vcpu *v, - unsigned long addr, - unsigned long length, - unsigned long val) -{ - hvm_vioapic_t *s = &(v->domain->arch.hvm_domain.vioapic); - - ASSERT(s); - - addr &= 0xff; - - switch (addr) { - case IOAPIC_REG_SELECT: - s->ioregsel = val; - break; - - case IOAPIC_REG_WINDOW: - hvm_vioapic_write_indirect(s, addr, length, val); - break; - -#ifdef __ia64__ - case IOAPIC_REG_EOI: - ioapic_update_EOI(v->domain, val); - break; -#endif - - default: - break; - } -} - -static int hvm_vioapic_range(struct vcpu *v, unsigned long addr) -{ - hvm_vioapic_t *s = &(v->domain->arch.hvm_domain.vioapic); - - if ((s->flags & IOAPIC_ENABLE_FLAG) && - (addr >= s->base_address && - (addr < s->base_address + IOAPIC_MEM_LENGTH))) - return 1; - else - return 0; + switch ( addr ) + { + case VIOAPIC_REG_SELECT: + vioapic->ioregsel = val; + break; + + case VIOAPIC_REG_WINDOW: + vioapic_write_indirect(vioapic, addr, length, val); + break; + +#if VIOAPIC_IS_IOSAPIC + case VIOAPIC_REG_EOI: + vioapic_update_EOI(v->domain, val); + break; +#endif + + default: + break; + } +} + +static int vioapic_range(struct vcpu *v, unsigned long addr) +{ + struct vioapic *vioapic = domain_vioapic(v->domain); + + return ((addr >= vioapic->base_address && + (addr < vioapic->base_address + VIOAPIC_MEM_LENGTH))); } struct hvm_mmio_handler vioapic_mmio_handler = { - .check_handler = hvm_vioapic_range, - .read_handler = hvm_vioapic_read, - .write_handler = hvm_vioapic_write + .check_handler = vioapic_range, + .read_handler = vioapic_read, + .write_handler = vioapic_write }; -static void hvm_vioapic_reset(hvm_vioapic_t *s) +static void vioapic_reset(struct vioapic *vioapic) { int i; - memset(s, 0, sizeof(hvm_vioapic_t)); - - for (i = 0; i < IOAPIC_NUM_PINS; i++) { - s->redirtbl[i].RedirForm.mask = 0x1; - hvm_vioapic_update_imr(s, i); - } -} - -static void ioapic_update_config(hvm_vioapic_t *s, - unsigned long address, - uint8_t enable) -{ - ASSERT(s); - - ioapic_enable(s, enable); - - if (address != s->base_address) - s->base_address = address; -} - -static int ioapic_inj_irq(hvm_vioapic_t *s, + memset(vioapic, 0, sizeof(*vioapic)); + + for ( i = 0; i < VIOAPIC_NUM_PINS; i++ ) + { + vioapic->redirtbl[i].fields.mask = 0x1; + vioapic_update_imr(vioapic, i); + } +} + +static int ioapic_inj_irq(struct vioapic *vioapic, struct vlapic * target, uint8_t vector, uint8_t trig_mode, @@ -307,65 +278,64 @@ static int ioapic_inj_irq(hvm_vioapic_t { int result = 0; - ASSERT(s && target); - HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_inj_irq " - "irq %d trig %d delive mode %d\n", - vector, trig_mode, delivery_mode); - - switch (delivery_mode) { + "irq %d trig %d delive mode %d\n", + vector, trig_mode, delivery_mode); + + switch ( delivery_mode ) + { case dest_Fixed: case dest_LowestPrio: - if (vlapic_set_irq(target, vector, trig_mode) && (trig_mode == 1)) - printk("<ioapic_inj_irq> level interrupt happen before cleared\n"); + if ( vlapic_set_irq(target, vector, trig_mode) && (trig_mode == 1) ) + gdprintk(XENLOG_WARNING, "level interrupt before cleared\n"); result = 1; break; default: - printk("<ioapic_inj_irq> error delivery mode %d\n", - delivery_mode); - break; - } - - return result; + gdprintk(XENLOG_WARNING, "error delivery mode %d\n", delivery_mode); + break; + } + + return result; } #ifndef __ia64__ -static int ioapic_match_logical_addr(hvm_vioapic_t *s, int number, uint8_t dest) +static int ioapic_match_logical_addr( + struct vioapic *vioapic, int number, uint8_t dest) { int result = 0; - uint32_t logical_dest = vlapic_get_reg(s->lapic_info[number], APIC_LDR); - - ASSERT(s && s->lapic_info[number]); + uint32_t logical_dest; HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_match_logical_addr " - "number %i dest %x\n", - number, dest); - - switch (vlapic_get_reg(s->lapic_info[number], APIC_DFR)) + "number %i dest %x\n", + number, dest); + + logical_dest = vlapic_get_reg(vioapic->lapic_info[number], APIC_LDR); + + switch ( vlapic_get_reg(vioapic->lapic_info[number], APIC_DFR) ) { case APIC_DFR_FLAT: - result = - (dest & GET_APIC_LOGICAL_ID(logical_dest)) != 0; + 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)) && + == ((dest >> 0x4) & 0xf)) && (logical_dest & (dest & 0xf)) ) result = 1; break; default: - printk("error DFR value for %x local apic\n", number); + gdprintk(XENLOG_WARNING, "error DFR value for %x lapic\n", number); break; } return result; } #else -extern int ioapic_match_logical_addr(hvm_vioapic_t *s, int number, uint8_t dest); -#endif - -static uint32_t ioapic_get_delivery_bitmask(hvm_vioapic_t *s, +extern int ioapic_match_logical_addr( + struct vioapic *vioapic, int number, uint8_t dest); +#endif + +static uint32_t ioapic_get_delivery_bitmask(struct vioapic *vioapic, uint16_t dest, uint8_t dest_mode, uint8_t vector, @@ -375,18 +345,16 @@ static uint32_t ioapic_get_delivery_bitm int i; 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, s->lapic_count); - - ASSERT(s); + "dest %d dest_mode %d " + "vector %d del_mode %d, lapic_count %d\n", + dest, dest_mode, vector, delivery_mode, vioapic->lapic_count); if ( dest_mode == 0 ) { /* Physical mode. */ - for ( i = 0; i < s->lapic_count; i++ ) - { - if ( VLAPIC_ID(s->lapic_info[i]) == dest ) + for ( i = 0; i < vioapic->lapic_count; i++ ) + { + if ( VLAPIC_ID(vioapic->lapic_info[i]) == dest ) { mask = 1 << i; break; @@ -396,7 +364,7 @@ static uint32_t ioapic_get_delivery_bitm /* Broadcast. */ if ( dest == 0xFF ) { - for ( i = 0; i < s->lapic_count; i++ ) + for ( i = 0; i < vioapic->lapic_count; i++ ) mask |= ( 1 << i ); } } @@ -405,63 +373,67 @@ static uint32_t ioapic_get_delivery_bitm /* Logical destination. Call match_logical_addr for each APIC. */ if ( dest != 0 ) { - for ( i = 0; i < s->lapic_count; i++ ) + for ( i = 0; i < vioapic->lapic_count; i++ ) { - if ( s->lapic_info[i] && - ioapic_match_logical_addr(s, i, dest) ) + if ( vioapic->lapic_info[i] && + ioapic_match_logical_addr(vioapic, i, dest) ) mask |= (1<<i); } } } HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask " - "mask %x\n", mask); + "mask %x\n", mask); return mask; } -static void ioapic_deliver(hvm_vioapic_t *s, int irqno) -{ - uint16_t dest = s->redirtbl[irqno].RedirForm.dest_id; - uint8_t dest_mode = s->redirtbl[irqno].RedirForm.destmode; - uint8_t delivery_mode = s->redirtbl[irqno].RedirForm.deliver_mode; - uint8_t vector = s->redirtbl[irqno].RedirForm.vector; - uint8_t trig_mode = s->redirtbl[irqno].RedirForm.trigmod; +static void ioapic_deliver(struct vioapic *vioapic, int irq) +{ + uint16_t dest = vioapic->redirtbl[irq].fields.dest_id; + uint8_t dest_mode = vioapic->redirtbl[irq].fields.dest_mode; + uint8_t delivery_mode = vioapic->redirtbl[irq].fields.delivery_mode; + uint8_t vector = vioapic->redirtbl[irq].fields.vector; + uint8_t trig_mode = vioapic->redirtbl[irq].fields.trig_mode; uint32_t deliver_bitmask; struct vlapic *target; 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); + "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); - - if (!deliver_bitmask) { + vioapic, dest, dest_mode, vector, delivery_mode); + if ( !deliver_bitmask ) + { HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic deliver " - "no target on destination\n"); - + "no target on destination\n"); return; } - switch (delivery_mode) { + switch ( delivery_mode ) + { case dest_LowestPrio: { #ifdef IRQ0_SPECIAL_ROUTING /* Force round-robin to pick VCPU 0 */ - if (irqno == 0) - target = s->lapic_info[0]; + if ( irq == 0 ) + target = vioapic->lapic_info[0]; else #endif - target = apic_round_robin(s->domain, dest_mode, + target = apic_round_robin(vioapic_domain(vioapic), dest_mode, vector, deliver_bitmask); - if (target) { - ioapic_inj_irq(s, target, vector, trig_mode, delivery_mode); + if ( target != NULL ) + { + ioapic_inj_irq(vioapic, target, vector, trig_mode, delivery_mode); vcpu_kick(vlapic_vcpu(target)); - } else + } + else + { HVM_DBG_LOG(DBG_LEVEL_IOAPIC, - "null round robin mask %x vector %x delivery_mode %x\n", - deliver_bitmask, vector, dest_LowestPrio); + "null round robin mask %x vector %x delivery_mode %x\n", + deliver_bitmask, vector, dest_LowestPrio); + } break; } @@ -469,18 +441,21 @@ static void ioapic_deliver(hvm_vioapic_t case dest_ExtINT: { uint8_t bit; - for (bit = 0; bit < s->lapic_count; bit++) { + for ( bit = 0; bit < vioapic->lapic_count; bit++ ) + { if ( !(deliver_bitmask & (1 << bit)) ) continue; #ifdef IRQ0_SPECIAL_ROUTING /* Do not deliver timer interrupts to VCPU != 0 */ - if ( (irqno == 0) && (bit !=0 ) ) - target = s->lapic_info[0]; + if ( (irq == 0) && (bit != 0) ) + target = vioapic->lapic_info[0]; else #endif - target = s->lapic_info[bit]; - if (target) { - ioapic_inj_irq(s, target, vector, trig_mode, delivery_mode); + target = vioapic->lapic_info[bit]; + if ( target != NULL ) + { + ioapic_inj_irq(vioapic, target, vector, + trig_mode, delivery_mode); vcpu_kick(vlapic_vcpu(target)); } } @@ -492,164 +467,160 @@ static void ioapic_deliver(hvm_vioapic_t case dest_INIT: case dest__reserved_2: default: - printk("Not support delivey mode %d\n", delivery_mode); - break; - } -} - -static int ioapic_get_highest_irq(hvm_vioapic_t *s) -{ - uint32_t irqs = (s->irr | s->irr_xen) & ~s->isr & ~s->imr; + gdprintk(XENLOG_WARNING, "Unsupported delivery mode %d\n", + delivery_mode); + break; + } +} + +static int ioapic_get_highest_irq(struct vioapic *vioapic) +{ + uint32_t irqs = vioapic->irr | vioapic->irr_xen; + irqs &= ~vioapic->isr & ~vioapic->imr; return fls(irqs) - 1; } -static void service_ioapic(hvm_vioapic_t *s) -{ - int irqno; - - while ((irqno = ioapic_get_highest_irq(s)) != -1) { - - HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "service_ioapic " - "highest irqno %x\n", irqno); - - if (!test_bit(irqno, &s->imr)) { - ioapic_deliver(s, irqno); - } - - if (s->redirtbl[irqno].RedirForm.trigmod == IOAPIC_LEVEL_TRIGGER) { - s->isr |= (1 << irqno); - } - - s->irr &= ~(1 << irqno); - s->irr_xen &= ~(1 << irqno); - } -} - -void hvm_vioapic_set_xen_irq(struct domain *d, int irq, int level) -{ - hvm_vioapic_t *s = &d->arch.hvm_domain.vioapic; - - if (!IOAPICEnabled(s) || s->redirtbl[irq].RedirForm.mask) +static void service_ioapic(struct vioapic *vioapic) +{ + int irq; + + while ( (irq = ioapic_get_highest_irq(vioapic)) != -1 ) + { + HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "service_ioapic highest irq %x\n", irq); + + if ( !test_bit(irq, &vioapic->imr) ) + ioapic_deliver(vioapic, irq); + + if ( vioapic->redirtbl[irq].fields.trig_mode == VIOAPIC_LEVEL_TRIG ) + vioapic->isr |= (1 << irq); + + vioapic->irr &= ~(1 << irq); + vioapic->irr_xen &= ~(1 << irq); + } +} + +void vioapic_set_xen_irq(struct domain *d, int irq, int level) +{ + struct vioapic *vioapic = domain_vioapic(d); + + if ( vioapic->redirtbl[irq].fields.mask ) return; - if (s->redirtbl[irq].RedirForm.trigmod != IOAPIC_LEVEL_TRIGGER) - gdprintk(XENLOG_WARNING, "Forcing edge triggered APIC irq %d?\n", irq); - - if (level) - s->irr_xen |= 1 << irq; + if ( vioapic->redirtbl[irq].fields.trig_mode == VIOAPIC_EDGE_TRIG ) + gdprintk(XENLOG_WARNING, "Forcing edge triggered APIC irq %d?\n", irq); + + if ( level ) + vioapic->irr_xen |= 1 << irq; else - s->irr_xen &= ~(1 << irq); -} - -void hvm_vioapic_set_irq(struct domain *d, int irq, int level) -{ - hvm_vioapic_t *s = &(d->arch.hvm_domain.vioapic); + vioapic->irr_xen &= ~(1 << irq); +} + +void vioapic_set_irq(struct domain *d, int irq, int level) +{ + struct vioapic *vioapic = domain_vioapic(d); HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_set_irq " - "irq %x level %x\n", irq, level); - - if ( (irq < 0) || (irq >= IOAPIC_NUM_PINS) ) + "irq %x level %x\n", irq, level); + + if ( (irq < 0) || (irq >= VIOAPIC_NUM_PINS) ) return; - if ( !IOAPICEnabled(s) || s->redirtbl[irq].RedirForm.mask ) + if ( vioapic->redirtbl[irq].fields.mask ) return; - HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "hvm_vioapic_set_irq entry %x " - "vector %x deliver_mod %x destmode %x delivestatus %x " - "polarity %x remote_irr %x trigmod %x mask %x dest_id %x\n", - irq, - s->redirtbl[irq].RedirForm.vector, - s->redirtbl[irq].RedirForm.deliver_mode, - s->redirtbl[irq].RedirForm.destmode, - s->redirtbl[irq].RedirForm.delivestatus, - s->redirtbl[irq].RedirForm.polarity, - s->redirtbl[irq].RedirForm.remoteirr, - s->redirtbl[irq].RedirForm.trigmod, - s->redirtbl[irq].RedirForm.mask, - s->redirtbl[irq].RedirForm.dest_id); - - if (irq >= 0 && irq < IOAPIC_NUM_PINS) { + HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "vioapic_set_irq entry %x " + "vector %x delivery_mode %x dest_mode %x delivery_status %x " + "polarity %x remote_irr %x trig_mode %x mask %x dest_id %x\n", + irq, + vioapic->redirtbl[irq].fields.vector, + vioapic->redirtbl[irq].fields.delivery_mode, + vioapic->redirtbl[irq].fields.dest_mode, + vioapic->redirtbl[irq].fields.delivery_status, + vioapic->redirtbl[irq].fields.polarity, + vioapic->redirtbl[irq].fields.remote_irr, + vioapic->redirtbl[irq].fields.trig_mode, + vioapic->redirtbl[irq].fields.mask, + vioapic->redirtbl[irq].fields.dest_id); + + if ( (irq >= 0) && (irq < VIOAPIC_NUM_PINS) ) + { uint32_t bit = 1 << irq; - if (s->redirtbl[irq].RedirForm.trigmod == IOAPIC_LEVEL_TRIGGER) { - if (level) - s->irr |= bit; + if ( vioapic->redirtbl[irq].fields.trig_mode == VIOAPIC_LEVEL_TRIG ) + { + if ( level ) + vioapic->irr |= bit; else - s->irr &= ~bit; - } else { - if (level) + vioapic->irr &= ~bit; + } + else + { + if ( level ) /* XXX No irr clear for edge interrupt */ - s->irr |= bit; - } - } - - service_ioapic(s); + vioapic->irr |= bit; + } + } + + service_ioapic(vioapic); } /* XXX If level interrupt, use vector->irq table for performance */ -static int get_redir_num(hvm_vioapic_t *s, int vector) -{ - int i = 0; - - ASSERT(s); - - for(i = 0; i < IOAPIC_NUM_PINS; i++) { - if (s->redirtbl[i].RedirForm.vector == vector) +static int get_redir_num(struct vioapic *vioapic, int vector) +{ + int i; + + for ( i = 0; i < VIOAPIC_NUM_PINS; i++ ) + if ( vioapic->redirtbl[i].fields.vector == vector ) return i; - } return -1; } -void ioapic_update_EOI(struct domain *d, int vector) -{ - hvm_vioapic_t *s = &(d->arch.hvm_domain.vioapic); +void vioapic_update_EOI(struct domain *d, int vector) +{ + struct vioapic *vioapic = domain_vioapic(d); int redir_num; - if ((redir_num = get_redir_num(s, vector)) == -1) { - printk("Can't find redir item for %d EOI \n", vector); + if ( (redir_num = get_redir_num(vioapic, vector)) == -1 ) + { + gdprintk(XENLOG_WARNING, "Can't find redir item for %d EOI\n", vector); return; } - if (!test_and_clear_bit(redir_num, &s->isr)) { - printk("redir %d not set for %d EOI\n", redir_num, vector); + if ( !test_and_clear_bit(redir_num, &vioapic->isr) ) + { + gdprintk(XENLOG_WARNING, "redir %d not set for %d EOI\n", + redir_num, vector); return; } } -int hvm_vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v) -{ - hvm_vioapic_t *s = &(v->domain->arch.hvm_domain.vioapic); - - if (v->vcpu_id != s->lapic_count) { - printk("hvm_vioapic_add_lapic " - "cpu_id not match vcpu_id %x lapic_count %x\n", - v->vcpu_id, s->lapic_count); +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 */ - s->lapic_info[s->lapic_count] = vlapic; - s->lapic_count ++; - - return s->lapic_count; -} - -hvm_vioapic_t * hvm_vioapic_init(struct domain *d) -{ - int i = 0; - hvm_vioapic_t *s = &(d->arch.hvm_domain.vioapic); - - HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "hvm_vioapic_init\n"); - - hvm_vioapic_reset(s); - - s->domain = d; - - for (i = 0; i < MAX_LAPIC_NUM; i++) - s->lapic_info[i] = NULL; - - /* Remove after GFW ready */ - ioapic_update_config(s, IOAPIC_DEFAULT_BASE_ADDRESS, 1); - - return s; -} + /* 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); + + HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "vioapic_init\n"); + + vioapic_reset(vioapic); + + vioapic->base_address = VIOAPIC_DEFAULT_BASE_ADDRESS; +} diff -r 9fbb26d47b83 -r cba947bc8450 xen/arch/x86/hvm/vlapic.c --- a/xen/arch/x86/hvm/vlapic.c Tue Nov 07 15:48:10 2006 +0000 +++ b/xen/arch/x86/hvm/vlapic.c Tue Nov 07 17:46:40 2006 +0000 @@ -432,7 +432,7 @@ void vlapic_EOI_set(struct vlapic *vlapi vlapic_clear_vector(vector, vlapic->regs + APIC_ISR); if ( vlapic_test_and_clear_vector(vector, vlapic->regs + APIC_TMR) ) - ioapic_update_EOI(vlapic_domain(vlapic), vector); + vioapic_update_EOI(vlapic_domain(vlapic), vector); } static void vlapic_ipi(struct vlapic *vlapic) @@ -1001,7 +1001,7 @@ int vlapic_init(struct vcpu *v) if ( v->vcpu_id == 0 ) vlapic->apic_base_msr |= MSR_IA32_APICBASE_BSP; - hvm_vioapic_add_lapic(vlapic, v); + vioapic_add_lapic(vlapic, v); init_timer(&vlapic->vlapic_timer, vlapic_timer_fn, vlapic, v->processor); diff -r 9fbb26d47b83 -r cba947bc8450 xen/arch/x86/hvm/vmx/io.c --- a/xen/arch/x86/hvm/vmx/io.c Tue Nov 07 15:48:10 2006 +0000 +++ b/xen/arch/x86/hvm/vmx/io.c Tue Nov 07 17:46:40 2006 +0000 @@ -99,7 +99,7 @@ asmlinkage void vmx_intr_assist(void) struct vlapic *vlapic = vcpu_vlapic(v); struct hvm_domain *plat=&v->domain->arch.hvm_domain; struct periodic_time *pt = &plat->pl_time.periodic_tm; - struct hvm_virpic *pic= &plat->vpic; + struct vpic *pic= &plat->vpic; unsigned int idtv_info_field; unsigned long inst_len; int has_ext_irq; diff -r 9fbb26d47b83 -r cba947bc8450 xen/include/asm-ia64/vmx_platform.h --- a/xen/include/asm-ia64/vmx_platform.h Tue Nov 07 15:48:10 2006 +0000 +++ b/xen/include/asm-ia64/vmx_platform.h Tue Nov 07 17:46:40 2006 +0000 @@ -32,7 +32,7 @@ typedef struct virtual_platform_def { unsigned long params[HVM_NR_PARAMS]; struct mmio_list *mmio; /* One IOSAPIC now... */ - struct hvm_vioapic vioapic; + struct vioapic vioapic; } vir_plat_t; static inline int __fls(uint32_t word) diff -r 9fbb26d47b83 -r cba947bc8450 xen/include/asm-x86/hvm/domain.h --- a/xen/include/asm-x86/hvm/domain.h Tue Nov 07 15:48:10 2006 +0000 +++ b/xen/include/asm-x86/hvm/domain.h Tue Nov 07 17:46:40 2006 +0000 @@ -35,8 +35,8 @@ struct hvm_domain { s64 tsc_frequency; struct pl_time pl_time; - struct hvm_virpic vpic; - struct hvm_vioapic vioapic; + struct vpic vpic; + struct vioapic vioapic; struct hvm_io_handler io_handler; unsigned char round_info[256]; diff -r 9fbb26d47b83 -r cba947bc8450 xen/include/asm-x86/hvm/vioapic.h --- a/xen/include/asm-x86/hvm/vioapic.h Tue Nov 07 15:48:10 2006 +0000 +++ b/xen/include/asm-x86/hvm/vioapic.h Tue Nov 07 17:46:40 2006 +0000 @@ -23,97 +23,90 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __ASM_X86_HVM_IOAPIC_H__ -#define __ASM_X86_HVM_IOAPIC_H__ +#ifndef __ASM_X86_HVM_VIOAPIC_H__ +#define __ASM_X86_HVM_VIOAPIC_H__ #include <xen/config.h> #include <xen/types.h> #include <xen/smp.h> -#ifndef __ia64__ -#define IOAPIC_VERSION_ID 0x11 -#else -#define IOAPIC_VERSION_ID 0x21 +#ifdef __ia64__ +#define VIOAPIC_IS_IOSAPIC 1 #endif -#define IOAPIC_NUM_PINS 24 -#define MAX_LAPIC_NUM 32 - -#define IOAPIC_LEVEL_TRIGGER 1 - -#define IOAPIC_DEFAULT_BASE_ADDRESS 0xfec00000 -#define IOAPIC_MEM_LENGTH 0x100 - -#define IOAPIC_ENABLE_MASK 0x0 -#define IOAPIC_ENABLE_FLAG (1 << IOAPIC_ENABLE_MASK) -#define IOAPICEnabled(s) (s->flags & IOAPIC_ENABLE_FLAG) - -#define IOAPIC_REG_SELECT 0x0 -#define IOAPIC_REG_WINDOW 0x10 - -#ifdef __ia64__ -#define IOAPIC_REG_ASSERTION 0x20 -#define IOAPIC_REG_EOI 0x40 +#if !VIOAPIC_IS_IOSAPIC +#define VIOAPIC_VERSION_ID 0x11 /* IOAPIC version */ +#else +#define VIOAPIC_VERSION_ID 0x21 /* IOSAPIC version */ #endif -#ifndef __ia64__ -#define IOAPIC_REG_APIC_ID 0x0 -#define IOAPIC_REG_ARB_ID 0x2 -#endif +#define VIOAPIC_NUM_PINS 24 -#define IOAPIC_REG_VERSION 0x1 +#define VIOAPIC_EDGE_TRIG 0 +#define VIOAPIC_LEVEL_TRIG 1 -typedef union RedirStatus +#define VIOAPIC_DEFAULT_BASE_ADDRESS 0xfec00000 +#define VIOAPIC_MEM_LENGTH 0x100 + +/* Direct registers. */ +#define VIOAPIC_REG_SELECT 0x00 +#define VIOAPIC_REG_WINDOW 0x10 +#define VIOAPIC_REG_EOI 0x40 /* IA64 IOSAPIC only */ + +/* Indirect registers. */ +#define VIOAPIC_REG_APIC_ID 0x00 /* x86 IOAPIC only */ +#define VIOAPIC_REG_VERSION 0x01 +#define VIOAPIC_REG_ARB_ID 0x02 /* x86 IOAPIC only */ + +#define domain_vioapic(d) (&(d)->arch.hvm_domain.vioapic) +#define vioapic_domain(v) (container_of((v), struct domain, \ + arch.hvm_domain.vioapic)) + +union vioapic_redir_entry { - uint64_t value; + uint64_t bits; struct { uint8_t vector; - uint8_t deliver_mode:3; - uint8_t destmode:1; - uint8_t delivestatus:1; + uint8_t delivery_mode:3; + uint8_t dest_mode:1; + uint8_t delivery_status:1; uint8_t polarity:1; - uint8_t remoteirr:1; - uint8_t trigmod:1; - uint8_t mask:1; /* interrupt mask*/ + uint8_t remote_irr:1; + uint8_t trig_mode:1; + uint8_t mask:1; uint8_t reserve:7; -#ifndef __ia64__ +#if !VIOAPIC_IS_IOSAPIC uint8_t reserved[4]; uint8_t dest_id; #else uint8_t reserved[3]; uint16_t dest_id; #endif - } RedirForm; -} RedirStatus; + } fields; +}; -typedef struct hvm_vioapic { +struct vioapic { uint32_t irr; uint32_t irr_xen; /* interrupts forced on by the hypervisor. */ - uint32_t isr; /* This is used for level trigger */ + uint32_t isr; /* This is used for level trigger */ uint32_t imr; uint32_t ioregsel; - uint32_t flags; + uint32_t id; + unsigned long base_address; + union vioapic_redir_entry redirtbl[VIOAPIC_NUM_PINS]; + struct vlapic *lapic_info[32]; uint32_t lapic_count; - uint32_t id; - uint32_t arb_id; - unsigned long base_address; - RedirStatus redirtbl[IOAPIC_NUM_PINS]; - struct vlapic *lapic_info[MAX_LAPIC_NUM]; - struct domain *domain; -} hvm_vioapic_t; +}; -hvm_vioapic_t *hvm_vioapic_init(struct domain *d); - -void hvm_vioapic_set_xen_irq(struct domain *d, int irq, int level); -void hvm_vioapic_set_irq(struct domain *d, int irq, int level); - -int hvm_vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v); - -void ioapic_update_EOI(struct domain *d, int vector); +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_IOAPIC_H__ */ +#endif /* __ASM_X86_HVM_VIOAPIC_H__ */ diff -r 9fbb26d47b83 -r cba947bc8450 xen/include/asm-x86/hvm/vpic.h --- a/xen/include/asm-x86/hvm/vpic.h Tue Nov 07 15:48:10 2006 +0000 +++ b/xen/include/asm-x86/hvm/vpic.h Tue Nov 07 17:46:40 2006 +0000 @@ -5,10 +5,10 @@ * Copyright (c) 2005 Intel Corp * * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in @@ -18,19 +18,17 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. */ #ifndef __ASM_X86_HVM_VPIC_H__ #define __ASM_X86_HVM_VPIC_H__ -#define hw_error(x) do {} while (0); +#define domain_vpic(d) (&(d)->arch.hvm_domain.vpic) +#define vpic_domain(v) (container_of((v), struct domain, arch.hvm_domain.vpic)) - -/* i8259.c */ -typedef struct IOAPICState IOAPICState; typedef struct PicState { uint8_t last_irr; /* edge detection */ uint8_t irr; /* interrupt request register */ @@ -50,12 +48,11 @@ typedef struct PicState { uint8_t init4; /* true if 4 byte init */ uint8_t elcr; /* PIIX edge/trigger selection*/ uint8_t elcr_mask; - struct hvm_virpic *pics_state; + struct vpic *pics_state; } PicState; -struct hvm_virpic { +struct vpic { /* 0 is master pic, 1 is slave pic */ - /* XXX: better separation between the two pics */ PicState pics[2]; void (*irq_request)(void *opaque, int level); void *irq_request_opaque; @@ -63,13 +60,12 @@ struct hvm_virpic { spinlock_t lock; }; - void pic_set_xen_irq(void *opaque, int irq, int level); -void pic_set_irq(struct hvm_virpic *s, int irq, int level); -void pic_init(struct hvm_virpic *s, +void pic_set_irq(struct vpic *vpic, int irq, int level); +void pic_init(struct vpic *vpic, void (*irq_request)(void *, int), void *irq_request_opaque); -void pic_update_irq(struct hvm_virpic *s); /* Caller must hold s->lock */ +void pic_update_irq(struct vpic *vpic); /* Caller must hold vpic->lock */ void register_pic_io_hook(struct domain *d); int cpu_get_pic_interrupt(struct vcpu *v, int *type); int is_periodic_irq(struct vcpu *v, int irq, int type); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |