[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.