[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [IA64] Create a vlsapic - viosapic interface



# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1204919066 25200
# Node ID d5bcf03596ccdc56828ffd3de1d86ff62d774ade
# Parent  54c7e3798464dfa2e2ba1d725126cceaf935155b
[IA64] Create a vlsapic - viosapic interface

This patch removes duplicated code and create a vlsapic function to
inject any interruption.  Slightly simplifies vlsapic.

It also removes useless irq_save/restore around atomic updates.

Signed-off-by: Tristan Gingold <tgingold@xxxxxxx>
---
 xen/arch/ia64/vmx/viosapic.c   |   34 ++------------
 xen/arch/ia64/vmx/vlsapic.c    |   99 +++++++++++++++++++++--------------------
 xen/include/asm-ia64/vlsapic.h |    6 +-
 3 files changed, 62 insertions(+), 77 deletions(-)

diff -r 54c7e3798464 -r d5bcf03596cc xen/arch/ia64/vmx/viosapic.c
--- a/xen/arch/ia64/vmx/viosapic.c      Fri Mar 07 12:26:27 2008 -0700
+++ b/xen/arch/ia64/vmx/viosapic.c      Fri Mar 07 12:44:26 2008 -0700
@@ -49,36 +49,14 @@ static void viosapic_deliver(struct vios
     uint16_t dest = viosapic->redirtbl[irq].dest_id;
     uint8_t delivery_mode = viosapic->redirtbl[irq].delivery_mode;
     uint8_t vector = viosapic->redirtbl[irq].vector;
-    struct vcpu *v;
 
     ASSERT(spin_is_locked(&viosapic->lock));
-    switch ( delivery_mode )
-    {
-    case SAPIC_FIXED:
-    {
-        v = vlsapic_lid_to_vcpu(viosapic_domain(viosapic), dest);
-        vlsapic_set_irq(v, vector);
-        vcpu_kick(v);
-        break;
-    }
-    case SAPIC_LOWEST_PRIORITY:
-    {
-        v = vlsapic_lid_to_vcpu(viosapic_domain(viosapic), dest);
-        if (viosapic->lowest_vcpu)
-            v = viosapic->lowest_vcpu;
-        vlsapic_set_irq(v, vector);
-        vcpu_kick(v);
-        break;
-    }
-    case SAPIC_PMI:
-    case SAPIC_NMI:
-    case SAPIC_INIT:
-    case SAPIC_EXTINT:
-    default:
-        gdprintk(XENLOG_WARNING, "Unsupported delivery mode %d\n",
-                 delivery_mode);
-        break;
-    }
+
+    if (vlsapic_deliver_int(viosapic_domain (viosapic),
+                            dest, delivery_mode, vector) < 0)
+        gdprintk(XENLOG_WARNING,
+                 "viosapic: can't deliver int %u to %u (dm=%u)\n",
+                 vector, dest, delivery_mode);
 }
 
 
diff -r 54c7e3798464 -r d5bcf03596cc xen/arch/ia64/vmx/vlsapic.c
--- a/xen/arch/ia64/vmx/vlsapic.c       Fri Mar 07 12:26:27 2008 -0700
+++ b/xen/arch/ia64/vmx/vlsapic.c       Fri Mar 07 12:44:26 2008 -0700
@@ -107,7 +107,6 @@ static void update_vhpi(VCPU *vcpu, int 
  */
 static int vmx_vcpu_unpend_interrupt(VCPU *vcpu, uint8_t vector)
 {
-    uint64_t spsr;
     int ret;
 
     if (vector & ~0xff) {
@@ -115,9 +114,7 @@ static int vmx_vcpu_unpend_interrupt(VCP
         return -1;
     }
 
-    local_irq_save(spsr);
     ret = test_and_clear_bit(vector, &VCPU(vcpu, irr[0]));
-    local_irq_restore(spsr);
 
     if (ret) {
         vcpu->arch.irq_new_pending = 1;
@@ -422,16 +419,13 @@ static int irq_masked(VCPU *vcpu, int h_
  */
 int vmx_vcpu_pend_interrupt(VCPU *vcpu, uint8_t vector)
 {
-    uint64_t    spsr;
     int ret;
 
     if (vector & ~0xff) {
         gdprintk(XENLOG_INFO, "vmx_vcpu_pend_interrupt: bad vector\n");
         return -1;
     }
-    local_irq_save(spsr);
     ret = test_and_set_bit(vector, &VCPU(vcpu, irr[0]));
-    local_irq_restore(spsr);
 
     if (!ret) {
         vcpu->arch.irq_new_pending = 1;
@@ -605,16 +599,15 @@ void vmx_vexirq(VCPU *vcpu)
     generate_exirq (vcpu);
 }
 
-struct vcpu * vlsapic_lid_to_vcpu(struct domain *d, uint16_t dest)
-{
-    struct vcpu * v;
-    for_each_vcpu ( d, v ) {
-        if ( (v->arch.privregs->lid >> 16) == dest )
-            return v;
-    }
+struct vcpu *lid_to_vcpu(struct domain *d, uint16_t dest)
+{
+    int id = dest >> 8;
+
+    /* Fast look: assume EID=0 ID=vcpu_id.  */
+    if ((dest & 0xff) == 0 && id < MAX_VIRT_CPUS)
+        return d->vcpu[id];
     return NULL;
 }
-
 
 /*
  * To inject INIT to guest, we must set the PAL_INIT entry 
@@ -641,14 +634,25 @@ static void vmx_inject_guest_pal_init(VC
  *  offset: address offset to IPI space.
  *  value:  deliver value.
  */
-static void vlsapic_deliver_ipi(VCPU *vcpu, uint64_t dm, uint64_t vector)
-{
-    IPI_DPRINTK("deliver_ipi %lx %lx\n", dm, vector);
+static int vcpu_deliver_int(VCPU *vcpu, uint64_t dm, uint64_t vector)
+{
+    int running = vcpu->is_running;
+
+    IPI_DPRINTK("deliver_int %lx %lx\n", dm, vector);
 
     switch (dm) {
     case SAPIC_FIXED:     // INT
         vmx_vcpu_pend_interrupt(vcpu, vector);
         break;
+    case SAPIC_LOWEST_PRIORITY:
+    {
+        struct vcpu *lowest = vcpu_viosapic(vcpu)->lowest_vcpu;
+
+        if (lowest == NULL)
+            lowest = vcpu;
+        vmx_vcpu_pend_interrupt(lowest, vector);
+        break;
+    }
     case SAPIC_PMI:
         // TODO -- inject guest PMI
         panic_domain(NULL, "Inject guest PMI!\n");
@@ -663,9 +667,30 @@ static void vlsapic_deliver_ipi(VCPU *vc
         vmx_vcpu_pend_interrupt(vcpu, 0);
         break;
     default:
-        panic_domain(NULL, "Deliver reserved IPI!\n");
-        break;
-    }
+        return -EINVAL;
+    }
+
+    /* Kick vcpu.  */
+    vcpu_unblock(vcpu);
+    if (running)
+        smp_send_event_check_cpu(vcpu->processor);
+
+    return 0;
+}
+
+int vlsapic_deliver_int(struct domain *d,
+                       uint16_t dest, uint64_t dm, uint64_t vector)
+{
+    VCPU *vcpu;
+
+    vcpu = lid_to_vcpu(d, dest);
+    if (vcpu == NULL)
+        return -ESRCH;
+
+    if (!vcpu->is_initialised || test_bit(_VPF_down, &vcpu->pause_flags))
+        return -ENOEXEC;
+
+    return vcpu_deliver_int (vcpu, dm, vector);
 }
 
 /*
@@ -673,25 +698,8 @@ static void vlsapic_deliver_ipi(VCPU *vc
  */
 void deliver_pal_init(VCPU *vcpu)
 {
-    vlsapic_deliver_ipi(vcpu, SAPIC_INIT, 0);
-}
-
-/*
- * TODO: Use hash table for the lookup.
- */
-static inline VCPU *lid_to_vcpu(struct domain *d, uint8_t id, uint8_t eid)
-{
-    VCPU  *v;
-    LID   lid; 
-
-    for_each_vcpu(d, v) {
-        lid.val = VCPU_LID(v);
-        if (lid.id == id && lid.eid == eid)
-            return v;
-    }
-    return NULL;
-}
-
+    vcpu_deliver_int(vcpu, SAPIC_INIT, 0);
+}
 
 /*
  * execute write IPI op.
@@ -701,7 +709,8 @@ static void vlsapic_write_ipi(VCPU *vcpu
     VCPU   *targ;
     struct domain *d = vcpu->domain; 
 
-    targ = lid_to_vcpu(vcpu->domain, ((ipi_a_t)addr).id, ((ipi_a_t)addr).eid);
+    targ = lid_to_vcpu(vcpu->domain,
+                       (((ipi_a_t)addr).id << 8) | ((ipi_a_t)addr).eid);
     if (targ == NULL)
         panic_domain(NULL, "Unknown IPI cpu\n");
 
@@ -727,12 +736,10 @@ static void vlsapic_write_ipi(VCPU *vcpu
             printk("arch_boot_vcpu: huh, already awake!");
         }
     } else {
-        int running = targ->is_running;
-        vlsapic_deliver_ipi(targ, ((ipi_d_t)value).dm, 
-                            ((ipi_d_t)value).vector);
-        vcpu_unblock(targ);
-        if (running)
-            smp_send_event_check_cpu(targ->processor);
+        if (((ipi_d_t)value).dm == SAPIC_LOWEST_PRIORITY ||
+            vcpu_deliver_int(targ, ((ipi_d_t)value).dm, 
+                             ((ipi_d_t)value).vector) < 0)
+            panic_domain(NULL, "Deliver reserved interrupt!\n");
     }
     return;
 }
diff -r 54c7e3798464 -r d5bcf03596cc xen/include/asm-ia64/vlsapic.h
--- a/xen/include/asm-ia64/vlsapic.h    Fri Mar 07 12:26:27 2008 -0700
+++ b/xen/include/asm-ia64/vlsapic.h    Fri Mar 07 12:44:26 2008 -0700
@@ -70,9 +70,9 @@ extern void vtm_set_itv(struct vcpu *vcp
 extern void vtm_set_itv(struct vcpu *vcpu, uint64_t val);
 extern void vmx_vexirq(struct vcpu  *vcpu);
 extern void vhpi_detection(struct vcpu *vcpu);
-extern int vmx_vcpu_pend_interrupt(VCPU * vcpu, uint8_t vector);
-extern struct vcpu * vlsapic_lid_to_vcpu(struct domain *d, uint16_t dest);
+extern int vlsapic_deliver_int(struct domain *d,
+                              uint16_t dest, uint64_t dm, uint64_t vector);
+
 extern uint64_t vlsapic_read(struct vcpu *v, uint64_t addr, uint64_t s);
 extern void vlsapic_write(struct vcpu *v, uint64_t addr, uint64_t s, uint64_t 
val);
-#define vlsapic_set_irq vmx_vcpu_pend_interrupt
 #endif

_______________________________________________
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®.