WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] x86 hvm: Clean up vlapic/vioapic/vmsi del

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86 hvm: Clean up vlapic/vioapic/vmsi delivery.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 19 Aug 2009 07:40:26 -0700
Delivery-date: Wed, 19 Aug 2009 07:42:11 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1250687632 -3600
# Node ID 017762c75beb46eae8996cce9c0761959a793f2b
# Parent  902f4ae65123813aaf660d3b8cf81eb5ba0fa6ff
x86 hvm: Clean up vlapic/vioapic/vmsi delivery.

In particular, avoid intermediate delivery bitmaps which restrict
number of vcpus supported.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/hvm/vioapic.c        |  106 ++++++++------------------------------
 xen/arch/x86/hvm/vlapic.c         |   81 +++++++++++------------------
 xen/arch/x86/hvm/vmsi.c           |   75 +++-----------------------
 xen/include/asm-ia64/hvm/vlapic.h |    2 
 xen/include/asm-x86/hvm/vlapic.h  |   12 ++--
 5 files changed, 72 insertions(+), 204 deletions(-)

diff -r 902f4ae65123 -r 017762c75beb xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c        Wed Aug 19 13:17:41 2009 +0100
+++ b/xen/arch/x86/hvm/vioapic.c        Wed Aug 19 14:13:52 2009 +0100
@@ -263,46 +263,6 @@ static void ioapic_inj_irq(
         vcpu_kick(vlapic_vcpu(target));
 }
 
-static uint32_t ioapic_get_delivery_bitmask(
-    struct hvm_hw_vioapic *vioapic, uint16_t dest, uint8_t dest_mode)
-{
-    uint32_t mask = 0;
-    struct vcpu *v;
-
-    HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "dest %d dest_mode %d",
-                dest, dest_mode);
-
-    if ( dest_mode == 0 ) /* Physical mode. */
-    {
-        if ( dest == 0xFF ) /* Broadcast. */
-        {
-            for_each_vcpu ( vioapic_domain(vioapic), v )
-                mask |= 1 << v->vcpu_id;
-            goto out;
-        }
-
-        for_each_vcpu ( vioapic_domain(vioapic), v )
-        {
-            if ( VLAPIC_ID(vcpu_vlapic(v)) == dest )
-            {
-                mask = 1 << v->vcpu_id;
-                break;
-            }
-        }
-    }
-    else if ( dest != 0 ) /* Logical mode, MDA non-zero. */
-    {
-        for_each_vcpu ( vioapic_domain(vioapic), v )
-            if ( vlapic_match_logical_addr(vcpu_vlapic(v), dest) )
-                mask |= 1 << v->vcpu_id;
-    }
-
- out:
-    HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "mask %x",
-                mask);
-    return mask;
-}
-
 static inline int pit_channel0_enabled(void)
 {
     PITState *pit = &current->domain->arch.hvm_domain.pl_time.vpit;
@@ -316,24 +276,17 @@ static void vioapic_deliver(struct hvm_h
     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 domain *d = vioapic_domain(vioapic);
     struct vlapic *target;
     struct vcpu *v;
 
-    ASSERT(spin_is_locked(&vioapic_domain(vioapic)->arch.hvm_domain.irq_lock));
+    ASSERT(spin_is_locked(&d->arch.hvm_domain.irq_lock));
 
     HVM_DBG_LOG(DBG_LEVEL_IOAPIC,
                 "dest=%x dest_mode=%x delivery_mode=%x "
                 "vector=%x trig_mode=%x",
                 dest, dest_mode, delivery_mode, vector, trig_mode);
 
-    deliver_bitmask = ioapic_get_delivery_bitmask(vioapic, dest, dest_mode);
-    if ( !deliver_bitmask )
-    {
-        HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "no target on destination");
-        return;
-    }
-
     switch ( delivery_mode )
     {
     case dest_LowestPrio:
@@ -342,14 +295,12 @@ static void vioapic_deliver(struct hvm_h
         /* Force round-robin to pick VCPU 0 */
         if ( (irq == hvm_isa_irq_to_gsi(0)) && pit_channel0_enabled() )
         {
-            v = vioapic_domain(vioapic)->vcpu ?
-                vioapic_domain(vioapic)->vcpu[0] : NULL;
+            v = d->vcpu ? d->vcpu[0] : NULL;
             target = v ? vcpu_vlapic(v) : NULL;
         }
         else
 #endif
-            target = apic_lowest_prio(vioapic_domain(vioapic),
-                                      deliver_bitmask);
+            target = vlapic_lowest_prio(d, NULL, 0, dest, dest_mode);
         if ( target != NULL )
         {
             ioapic_inj_irq(vioapic, target, vector, trig_mode, delivery_mode);
@@ -357,52 +308,41 @@ static void vioapic_deliver(struct hvm_h
         else
         {
             HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "null round robin: "
-                        "mask=%x vector=%x delivery_mode=%x",
-                        deliver_bitmask, vector, dest_LowestPrio);
+                        "vector=%x delivery_mode=%x",
+                        vector, dest_LowestPrio);
         }
         break;
     }
 
     case dest_Fixed:
     {
-        uint8_t bit;
-        for ( bit = 0; deliver_bitmask != 0; bit++ )
-        {
-            if ( !(deliver_bitmask & (1 << bit)) )
-                continue;
-            deliver_bitmask &= ~(1 << bit);
-            if ( vioapic_domain(vioapic)->vcpu == NULL )
-                v = NULL;
 #ifdef IRQ0_SPECIAL_ROUTING
-            /* Do not deliver timer interrupts to VCPU != 0 */
-            else if ( (irq == hvm_isa_irq_to_gsi(0)) && pit_channel0_enabled() 
)
-                v = vioapic_domain(vioapic)->vcpu[0];
-#endif
-            else
-                v = vioapic_domain(vioapic)->vcpu[bit];
-            if ( v != NULL )
-            {
-                target = vcpu_vlapic(v);
-                ioapic_inj_irq(vioapic, target, vector,
+        /* Do not deliver timer interrupts to VCPU != 0 */
+        if ( (irq == hvm_isa_irq_to_gsi(0)) && pit_channel0_enabled() )
+        {
+            if ( (v = d->vcpu ? d->vcpu[0] : NULL) != NULL )
+                ioapic_inj_irq(vioapic, vcpu_vlapic(v), vector,
                                trig_mode, delivery_mode);
-            }
+        }
+        else
+#endif
+        {
+            for_each_vcpu ( d, v )
+                if ( vlapic_match_dest(vcpu_vlapic(v), NULL,
+                                       0, dest, dest_mode) )
+                    ioapic_inj_irq(vioapic, vcpu_vlapic(v), vector,
+                                   trig_mode, delivery_mode);
         }
         break;
     }
 
     case dest_NMI:
     {
-        uint8_t bit;
-        for ( bit = 0; deliver_bitmask != 0; bit++ )
-        {
-            if ( !(deliver_bitmask & (1 << bit)) )
-                continue;
-            deliver_bitmask &= ~(1 << bit);
-            if ( (vioapic_domain(vioapic)->vcpu != NULL) &&
-                 ((v = vioapic_domain(vioapic)->vcpu[bit]) != NULL) &&
+        for_each_vcpu ( d, v )
+            if ( vlapic_match_dest(vcpu_vlapic(v), NULL,
+                                   0, dest, dest_mode) &&
                  !test_and_set_bool(v->nmi_pending) )
                 vcpu_kick(v);
-        }
         break;
     }
 
diff -r 902f4ae65123 -r 017762c75beb xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Wed Aug 19 13:17:41 2009 +0100
+++ b/xen/arch/x86/hvm/vlapic.c Wed Aug 19 14:13:52 2009 +0100
@@ -167,7 +167,7 @@ uint32_t vlapic_get_ppr(struct vlapic *v
     return ppr;
 }
 
-int vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t mda)
+static int vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t mda)
 {
     int result = 0;
     uint8_t logical_id;
@@ -194,12 +194,10 @@ int vlapic_match_logical_addr(struct vla
     return result;
 }
 
-static int vlapic_match_dest(struct vcpu *v, struct vlapic *source,
-                             int short_hand, int dest, int dest_mode)
-{
-    int result = 0;
-    struct vlapic *target = vcpu_vlapic(v);
-
+bool_t vlapic_match_dest(
+    struct vlapic *target, struct vlapic *source,
+    int short_hand, uint8_t dest, uint8_t dest_mode)
+{
     HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "target %p, source %p, dest 0x%x, "
                 "dest_mode 0x%x, short_hand 0x%x",
                 target, source, dest, dest_mode, short_hand);
@@ -207,39 +205,25 @@ static int vlapic_match_dest(struct vcpu
     switch ( short_hand )
     {
     case APIC_DEST_NOSHORT:
-        if ( dest_mode == 0 )
-        {
-            /* Physical mode. */
-            if ( (dest == 0xFF) || (dest == VLAPIC_ID(target)) )
-                result = 1;
-        }
-        else
-        {
-            /* Logical mode. */
-            result = vlapic_match_logical_addr(target, dest);
-        }
-        break;
+        if ( dest_mode )
+            return vlapic_match_logical_addr(target, dest);
+        return ((dest == 0xFF) || (dest == VLAPIC_ID(target)));
 
     case APIC_DEST_SELF:
-        if ( target == source )
-            result = 1;
-        break;
+        return (target == source);
 
     case APIC_DEST_ALLINC:
-        result = 1;
-        break;
+        return 1;
 
     case APIC_DEST_ALLBUT:
-        if ( target != source )
-            result = 1;
-        break;
+        return (target != source);
 
     default:
         gdprintk(XENLOG_WARNING, "Bad dest shorthand value %x\n", short_hand);
         break;
     }
 
-    return result;
+    return 0;
 }
 
 static int vlapic_vcpu_pause_async(struct vcpu *v)
@@ -376,8 +360,9 @@ static int vlapic_accept_irq(struct vcpu
     return rc;
 }
 
-/* This function is used by both ioapic and lapic.The bitmap is for vcpu_id. */
-struct vlapic *apic_lowest_prio(struct domain *d, uint32_t bitmap)
+struct vlapic *vlapic_lowest_prio(
+    struct domain *d, struct vlapic *source,
+    int short_hand, uint8_t dest, uint8_t dest_mode)
 {
     int old = d->arch.hvm_domain.irq.round_robin_prev_vcpu;
     uint32_t ppr, target_ppr = UINT_MAX;
@@ -390,7 +375,8 @@ struct vlapic *apic_lowest_prio(struct d
     do {
         v = v->next_in_list ? : d->vcpu[0];
         vlapic = vcpu_vlapic(v);
-        if ( test_bit(v->vcpu_id, &bitmap) && vlapic_enabled(vlapic) &&
+        if ( vlapic_match_dest(vlapic, source, short_hand, dest, dest_mode) &&
+             vlapic_enabled(vlapic) &&
              ((ppr = vlapic_get_ppr(vlapic)) < target_ppr) )
         {
             target = vlapic;
@@ -434,36 +420,33 @@ int vlapic_ipi(
 
     struct vlapic *target;
     struct vcpu *v;
-    uint32_t lpr_map = 0;
     int rc = X86EMUL_OKAY;
 
     HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "icr_high 0x%x, icr_low 0x%x, "
                 "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, "
                 "dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x",
                 icr_high, icr_low, short_hand, dest,
-                trig_mode, level, dest_mode, delivery_mode, vector);
-
-    for_each_vcpu ( vlapic_domain(vlapic), v )
-    {
-        if ( vlapic_match_dest(v, vlapic, short_hand, dest, dest_mode) )
-        {
-            if ( delivery_mode == APIC_DM_LOWEST )
-                __set_bit(v->vcpu_id, &lpr_map);
-            else
-                rc = vlapic_accept_irq(v, delivery_mode,
-                                       vector, level, trig_mode);
-        }
-
-        if ( rc != X86EMUL_OKAY )
-            break;
-    }
+                trig_mode, level, dest_mode, delivery_mode, vector);    
 
     if ( delivery_mode == APIC_DM_LOWEST )
     {
-        target = apic_lowest_prio(vlapic_domain(vlapic), lpr_map);
+        target = vlapic_lowest_prio(vlapic_domain(vlapic), vlapic,
+                                    short_hand, dest, dest_mode);
         if ( target != NULL )
             rc = vlapic_accept_irq(vlapic_vcpu(target), delivery_mode,
                                    vector, level, trig_mode);
+        return rc;
+    }
+
+    for_each_vcpu ( vlapic_domain(vlapic), v )
+    {
+        if ( vlapic_match_dest(vcpu_vlapic(v), vlapic,
+                               short_hand, dest, dest_mode) )
+                rc = vlapic_accept_irq(v, delivery_mode,
+                                       vector, level, trig_mode);
+
+        if ( rc != X86EMUL_OKAY )
+            break;
     }
 
     return rc;
diff -r 902f4ae65123 -r 017762c75beb xen/arch/x86/hvm/vmsi.c
--- a/xen/arch/x86/hvm/vmsi.c   Wed Aug 19 13:17:41 2009 +0100
+++ b/xen/arch/x86/hvm/vmsi.c   Wed Aug 19 14:13:52 2009 +0100
@@ -40,46 +40,6 @@
 #include <asm/current.h>
 #include <asm/event.h>
 
-static uint32_t vmsi_get_delivery_bitmask(
-    struct domain *d, uint16_t dest, uint8_t dest_mode)
-{
-    uint32_t mask = 0;
-    struct vcpu *v;
-
-    HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask "
-                "dest %d dest_mode %d\n", dest, dest_mode);
-
-    if ( dest_mode == 0 ) /* Physical mode. */
-    {
-        if ( dest == 0xFF ) /* Broadcast. */
-        {
-            for_each_vcpu ( d, v )
-                mask |= 1 << v->vcpu_id;
-            goto out;
-        }
-
-        for_each_vcpu ( d, v )
-        {
-            if ( VLAPIC_ID(vcpu_vlapic(v)) == dest )
-            {
-                mask = 1 << v->vcpu_id;
-                break;
-            }
-        }
-    }
-    else if ( dest != 0 ) /* Logical mode, MDA non-zero. */
-    {
-        for_each_vcpu ( d, v )
-            if ( vlapic_match_logical_addr(vcpu_vlapic(v), dest) )
-                mask |= 1 << v->vcpu_id;
-    }
-
- out:
-    HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask mask %x\n",
-                mask);
-    return mask;
-}
-
 static void vmsi_inj_irq(
     struct domain *d,
     struct vlapic *target,
@@ -87,7 +47,7 @@ static void vmsi_inj_irq(
     uint8_t trig_mode,
     uint8_t delivery_mode)
 {
-    HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_inj_irq "
+    HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "vmsi_inj_irq "
                 "irq %d trig %d delive mode %d\n",
                 vector, trig_mode, delivery_mode);
 
@@ -125,7 +85,6 @@ int vmsi_deliver(struct domain *d, int p
     uint8_t dest_mode = (flags & VMSI_DM_MASK) >> GFLAGS_SHIFT_DM;
     uint8_t delivery_mode = (flags & VMSI_DELIV_MASK) >> 
GLFAGS_SHIFT_DELIV_MODE;
     uint8_t trig_mode = (flags & VMSI_TRIG_MODE) >> GLFAGS_SHIFT_TRG_MODE;
-    uint32_t deliver_bitmask;
     struct vlapic *target;
     struct vcpu *v;
 
@@ -140,44 +99,28 @@ int vmsi_deliver(struct domain *d, int p
         return 0;
     }
 
-    deliver_bitmask = vmsi_get_delivery_bitmask(d, dest, dest_mode);
-    if ( !deliver_bitmask )
-    {
-        HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic deliver "
-                    "no target on destination\n");
-        return 0;
-    }
-
     switch ( delivery_mode )
     {
     case dest_LowestPrio:
     {
-        target = apic_lowest_prio(d, deliver_bitmask);
+        target = vlapic_lowest_prio(d, NULL, 0, dest, dest_mode);
         if ( target != NULL )
             vmsi_inj_irq(d, target, vector, trig_mode, delivery_mode);
         else
             HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "null round robin: "
-                        "mask=%x vector=%x delivery_mode=%x\n",
-                        deliver_bitmask, vector, dest_LowestPrio);
+                        "vector=%x delivery_mode=%x\n",
+                        vector, dest_LowestPrio);
         break;
     }
 
     case dest_Fixed:
     case dest_ExtINT:
     {
-        uint8_t bit;
-        for ( bit = 0; deliver_bitmask != 0; bit++ )
-        {
-            if ( !(deliver_bitmask & (1 << bit)) )
-                continue;
-            deliver_bitmask &= ~(1 << bit);
-            v = d->vcpu[bit];
-            if ( v != NULL )
-            {
-                target = vcpu_vlapic(v);
-                vmsi_inj_irq(d, target, vector, trig_mode, delivery_mode);
-            }
-        }
+        for_each_vcpu ( d, v )
+            if ( vlapic_match_dest(vcpu_vlapic(v), NULL,
+                                   0, dest, dest_mode) )
+                vmsi_inj_irq(d, vcpu_vlapic(v),
+                             vector, trig_mode, delivery_mode);
         break;
     }
 
diff -r 902f4ae65123 -r 017762c75beb xen/include/asm-ia64/hvm/vlapic.h
--- a/xen/include/asm-ia64/hvm/vlapic.h Wed Aug 19 13:17:41 2009 +0100
+++ b/xen/include/asm-ia64/hvm/vlapic.h Wed Aug 19 14:13:52 2009 +0100
@@ -1,6 +1,4 @@
 #ifndef __ASM_IA64_HVM_VLAPIC_H__
 #define __ASM_IA64_HVM_VLAPIC_H__
 
-int vlapic_match_logical_addr(struct vlapic *vlapic, uint16_t dest);
-
 #endif /* __ASM_IA64_HVM_VLAPIC_H__ */
diff -r 902f4ae65123 -r 017762c75beb xen/include/asm-x86/hvm/vlapic.h
--- a/xen/include/asm-x86/hvm/vlapic.h  Wed Aug 19 13:17:41 2009 +0100
+++ b/xen/include/asm-x86/hvm/vlapic.h  Wed Aug 19 14:13:52 2009 +0100
@@ -94,12 +94,16 @@ int vlapic_accept_pic_intr(struct vcpu *
 
 void vlapic_adjust_i8259_target(struct domain *d);
 
-struct vlapic *apic_lowest_prio(struct domain *d, uint32_t bitmap);
-
-int vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t mda);
-
 void vlapic_EOI_set(struct vlapic *vlapic);
 
 int vlapic_ipi(struct vlapic *vlapic, uint32_t icr_low, uint32_t icr_high);
 
+struct vlapic *vlapic_lowest_prio(
+    struct domain *d, struct vlapic *source,
+    int short_hand, uint8_t dest, uint8_t dest_mode);
+
+bool_t vlapic_match_dest(
+    struct vlapic *target, struct vlapic *source,
+    int short_hand, uint8_t dest, uint8_t dest_mode);
+
 #endif /* __ASM_X86_HVM_VLAPIC_H__ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86 hvm: Clean up vlapic/vioapic/vmsi delivery., Xen patchbot-unstable <=