[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [IA64] Change to new interrupt deliver mechanism.
# HG changeset patch # User awilliam@xxxxxxxxxxx # Node ID 0705db48d23cca452e33f7ab2bc01b0da27e759d # Parent 76d379e3f1d786858e4b8d34175f95e55ab1d8fa [IA64] Change to new interrupt deliver mechanism. Signed-off-by: Anthony Xu <anthony.xu@xxxxxxxxx> --- linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c | 13 ++ tools/ioemu/Makefile.target | 4 xen/arch/ia64/vmx/viosapic.c | 71 +++++----------- xen/arch/ia64/vmx/vmx_hypercall.c | 97 +++++++++++++++++----- xen/include/asm-ia64/viosapic.h | 12 +- 5 files changed, 117 insertions(+), 80 deletions(-) diff -r 76d379e3f1d7 -r 0705db48d23c linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c --- a/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c Fri Dec 01 11:12:00 2006 -0700 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c Fri Dec 01 11:40:57 2006 -0700 @@ -579,9 +579,16 @@ xencomm_privcmd_hvm_op(privcmd_hypercall case HVMOP_set_param: argsize = sizeof(xen_hvm_param_t); break; - case HVMOP_set_irq_level: - argsize = sizeof(xen_hvm_set_irq_level_t); - break; + case HVMOP_set_pci_intx_level: + argsize = sizeof(xen_hvm_set_pci_intx_level_t); + break; + case HVMOP_set_isa_irq_level: + argsize = sizeof(xen_hvm_set_isa_irq_level_t); + break; + case HVMOP_set_pci_link_route: + argsize = sizeof(xen_hvm_set_pci_link_route_t); + break; + default: printk("%s: unknown HVMOP %d\n", __func__, cmd); return -EINVAL; diff -r 76d379e3f1d7 -r 0705db48d23c tools/ioemu/Makefile.target --- a/tools/ioemu/Makefile.target Fri Dec 01 11:12:00 2006 -0700 +++ b/tools/ioemu/Makefile.target Fri Dec 01 11:40:57 2006 -0700 @@ -296,7 +296,7 @@ endif # qemu-dm objects ifeq ($(ARCH),ia64) -LIBOBJS=helper2.o exec-dm.o i8259-dm.o +LIBOBJS=helper2.o exec-dm.o i8259-dm.o piix_pci-dm.o else LIBOBJS=helper2.o exec-dm.o i8259-dm.o rtc-dm.o piix_pci-dm.o endif @@ -360,7 +360,7 @@ ifeq ($(TARGET_BASE_ARCH), i386) # Hardware support VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) ifeq ($(ARCH),ia64) -VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o piix_pci.o +VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o else VL_OBJS+= fdc.o serial.o pc.o endif diff -r 76d379e3f1d7 -r 0705db48d23c xen/arch/ia64/vmx/viosapic.c --- a/xen/arch/ia64/vmx/viosapic.c Fri Dec 01 11:12:00 2006 -0700 +++ b/xen/arch/ia64/vmx/viosapic.c Fri Dec 01 11:40:57 2006 -0700 @@ -70,9 +70,12 @@ static void viosapic_deliver(struct vios static int iosapic_get_highest_irq(struct viosapic *viosapic) { - uint32_t irqs = viosapic->irr | viosapic->irr_xen; - irqs &= ~viosapic->isr & ~viosapic->imr; - return fls(irqs) - 1; + uint64_t irqs = viosapic->irr & ~viosapic->isr ; + + if (irqs >> 32) + return (fls(irqs >> 32) - 1 + 32); + else + return fls(irqs) - 1; } @@ -95,14 +98,12 @@ static void service_iosapic(struct viosa while ( (irq = iosapic_get_highest_irq(viosapic)) != -1 ) { - if ( !test_bit(irq, &viosapic->imr) ) - viosapic_deliver(viosapic, irq); + viosapic_deliver(viosapic, irq); if ( viosapic->redirtbl[irq].trig_mode == SAPIC_LEVEL ) - viosapic->isr |= (1 << irq); - - viosapic->irr &= ~(1 << irq); - viosapic->irr_xen &= ~(1 << irq); + viosapic->isr |= (1UL << irq); + + viosapic->irr &= ~(1UL << irq); } } @@ -192,15 +193,6 @@ unsigned long viosapic_read(struct vcpu } -static inline void viosapic_update_imr(struct viosapic *viosapic, int index) -{ - if ( viosapic->redirtbl[index].mask ) - set_bit(index, &viosapic->imr); - else - clear_bit(index, &viosapic->imr); -} - - static void viosapic_write_indirect(struct viosapic *viosapic, unsigned long addr, unsigned long length, @@ -237,7 +229,6 @@ static void viosapic_write_indirect(stru (val & 0xffffffff); } viosapic->redirtbl[redir_index].bits = redir_content; - viosapic_update_imr(viosapic, redir_index); break; } } /* switch */ @@ -282,39 +273,14 @@ static void viosapic_reset(struct viosap for ( i = 0; i < VIOSAPIC_NUM_PINS; i++ ) { viosapic->redirtbl[i].mask = 0x1; - viosapic_update_imr(viosapic, i); } spin_lock_init(&viosapic->lock); } - -// this is used by VBD/VNIF to inject interrupt for VTI-domain -void viosapic_set_xen_irq(struct domain *d, int irq, int level) +void viosapic_set_irq(struct domain *d, int irq, int level) { struct viosapic *viosapic = domain_viosapic(d); - - spin_lock(&viosapic->lock); - if ( viosapic->redirtbl[irq].mask ) - goto out; - - if ( viosapic->redirtbl[irq].trig_mode == SAPIC_EDGE) - gdprintk(XENLOG_WARNING, "Forcing edge triggered APIC irq %d?\n", irq); - - if ( level ) - viosapic->irr_xen |= 1 << irq; - else - viosapic->irr_xen &= ~(1 << irq); - - service_iosapic(viosapic); -out: - spin_unlock(&viosapic->lock); -} - - -void viosapic_set_irq(struct domain *d, int irq, int level) -{ - struct viosapic *viosapic = domain_viosapic(d); - uint32_t bit; + uint64_t bit; spin_lock(&viosapic->lock); if ( (irq < 0) || (irq >= VIOSAPIC_NUM_PINS) ) @@ -323,7 +289,7 @@ void viosapic_set_irq(struct domain *d, if ( viosapic->redirtbl[irq].mask ) goto out; - bit = 1 << irq; + bit = 1UL << irq; if ( viosapic->redirtbl[irq].trig_mode == SAPIC_LEVEL ) { if ( level ) @@ -343,6 +309,17 @@ out: spin_unlock(&viosapic->lock); } +#define hvm_pci_intx_gsi(dev, intx) \ + (((((dev) << 2) + ((dev) >> 3) + (intx)) & 31) + 16) + + +void viosapic_set_pci_irq(struct domain *d, int device, int intx, int level) +{ + int irq; + irq = hvm_pci_intx_gsi(device, intx); + + viosapic_set_irq(d, irq, level); +} void viosapic_init(struct domain *d) { diff -r 76d379e3f1d7 -r 0705db48d23c xen/arch/ia64/vmx/vmx_hypercall.c --- a/xen/arch/ia64/vmx/vmx_hypercall.c Fri Dec 01 11:12:00 2006 -0700 +++ b/xen/arch/ia64/vmx/vmx_hypercall.c Fri Dec 01 11:40:57 2006 -0700 @@ -36,6 +36,72 @@ #include <xen/domain.h> #include <asm/vmx.h> #include <asm/viosapic.h> + +static int hvmop_set_isa_irq_level( + XEN_GUEST_HANDLE(xen_hvm_set_isa_irq_level_t) uop) +{ + struct xen_hvm_set_isa_irq_level op; + struct domain *d; + int rc; + + if ( copy_from_guest(&op, uop, 1) ) + return -EFAULT; + + if ( !IS_PRIV(current->domain) ) + return -EPERM; + + if ( op.isa_irq > 15 ) + return -EINVAL; + + d = find_domain_by_id(op.domid); + if ( d == NULL ) + return -ESRCH; + + rc = -EINVAL; + if ( !is_hvm_domain(d) ) + goto out; + + rc = 0; + viosapic_set_irq(d, op.isa_irq, op.level); + + out: + put_domain(d); + return rc; +} + +static int hvmop_set_pci_intx_level( + XEN_GUEST_HANDLE(xen_hvm_set_pci_intx_level_t) uop) +{ + struct xen_hvm_set_pci_intx_level op; + struct domain *d; + int rc; + + if ( copy_from_guest(&op, uop, 1) ) + return -EFAULT; + + if ( !IS_PRIV(current->domain) ) + return -EPERM; + + if ( (op.domain > 0) || (op.bus > 0) || (op.device > 31) || (op.intx > 3) ) + return -EINVAL; + + d = find_domain_by_id(op.domid); + if ( d == NULL ) + return -ESRCH; + + rc = -EINVAL; + if ( !is_hvm_domain(d) ) + goto out; + + rc = 0; + viosapic_set_pci_irq(d, op.device, op.intx, op.level); + + out: + put_domain(d); + return rc; +} + + long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg) @@ -80,30 +146,19 @@ do_hvm_op(unsigned long op, XEN_GUEST_HA break; } - case HVMOP_set_irq_level: - { - struct xen_hvm_set_irq_level op; - struct domain *d; + case HVMOP_set_pci_intx_level: + rc = hvmop_set_pci_intx_level( + guest_handle_cast(arg, xen_hvm_set_pci_intx_level_t)); + break; - if (copy_from_guest(&op, arg, 1)) - return -EFAULT; + case HVMOP_set_isa_irq_level: + rc = hvmop_set_isa_irq_level( + guest_handle_cast(arg, xen_hvm_set_isa_irq_level_t)); + break; - if (!IS_PRIV(current->domain)) - return -EPERM; - - d = find_domain_by_id(op.domid); - if (d == NULL) - return -ESRCH; - - rc = -EINVAL; - if (is_hvm_domain(d)) { - viosapic_set_irq(d, op.irq, op.level); - rc = 0; - } - - put_domain(d); + case HVMOP_set_pci_link_route: + rc = 0; break; - } default: gdprintk(XENLOG_INFO, "Bad HVM op %ld.\n", op); diff -r 76d379e3f1d7 -r 0705db48d23c xen/include/asm-ia64/viosapic.h --- a/xen/include/asm-ia64/viosapic.h Fri Dec 01 11:12:00 2006 -0700 +++ b/xen/include/asm-ia64/viosapic.h Fri Dec 01 11:40:57 2006 -0700 @@ -42,7 +42,7 @@ #define VIOSAPIC_VERSION_ID 0x21 /* IOSAPIC version */ -#define VIOSAPIC_NUM_PINS 24 +#define VIOSAPIC_NUM_PINS 48 #define VIOSAPIC_DEFAULT_BASE_ADDRESS 0xfec00000 #define VIOSAPIC_MEM_LENGTH 0x100 @@ -74,19 +74,17 @@ union viosapic_rte }; struct viosapic { - uint32_t irr; - uint32_t irr_xen; /* interrupts forced on by the hypervisor. */ - uint32_t isr; /* This is used for level trigger */ - uint32_t imr; + uint64_t irr; + uint64_t isr; /* This is used for level trigger */ uint32_t ioregsel; spinlock_t lock; - unsigned long base_address; + uint64_t base_address; union viosapic_rte redirtbl[VIOSAPIC_NUM_PINS]; }; void viosapic_init(struct domain *d); -void viosapic_set_xen_irq(struct domain *d, int irq, int level); void viosapic_set_irq(struct domain *d, int irq, int level); +void viosapic_set_pci_irq(struct domain *d, int device, int intx, int level); void viosapic_write(struct vcpu *v, unsigned long addr, unsigned long length, unsigned long val); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |