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

[Xen-changelog] [xen-unstable] hvm: Reduce vpt.c dependencies on external timer details.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1197474080 0
# Node ID 4553bc1087d9f73e5c27f5511c1d4c724b4dbccf
# Parent  20898120c8f9b56902ceedb8deaf977175445f2f
hvm: Reduce vpt.c dependencies on external timer details.
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/hvm/i8254.c         |    2 
 xen/arch/x86/hvm/irq.c           |   25 --------
 xen/arch/x86/hvm/rtc.c           |   10 ---
 xen/arch/x86/hvm/vlapic.c        |   17 ------
 xen/arch/x86/hvm/vpt.c           |  110 +++++++++++++++++++++++++--------------
 xen/include/asm-x86/hvm/irq.h    |    3 -
 xen/include/asm-x86/hvm/vlapic.h |    3 -
 xen/include/asm-x86/hvm/vpt.h    |   11 ++-
 8 files changed, 87 insertions(+), 94 deletions(-)

diff -r 20898120c8f9 -r 4553bc1087d9 xen/arch/x86/hvm/i8254.c
--- a/xen/arch/x86/hvm/i8254.c  Wed Dec 12 12:02:01 2007 +0000
+++ b/xen/arch/x86/hvm/i8254.c  Wed Dec 12 15:41:20 2007 +0000
@@ -501,6 +501,8 @@ void pit_init(struct vcpu *v, unsigned l
     /* Some sub-functions assert that they are called with the lock held. */
     spin_lock(&pit->lock);
 
+    pit->pt0.source = PTSRC_isa;
+
     register_portio_handler(v->domain, PIT_BASE, 4, handle_pit_io);
     register_portio_handler(v->domain, 0x61, 1, handle_speaker_io);
     ticks_per_sec(v) = cpu_khz * (int64_t)1000;
diff -r 20898120c8f9 -r 4553bc1087d9 xen/arch/x86/hvm/irq.c
--- a/xen/arch/x86/hvm/irq.c    Wed Dec 12 12:02:01 2007 +0000
+++ b/xen/arch/x86/hvm/irq.c    Wed Dec 12 15:41:20 2007 +0000
@@ -345,31 +345,6 @@ struct hvm_intack hvm_vcpu_ack_pending_i
     }
 
     return intack;
-}
-
-int get_isa_irq_vector(struct vcpu *v, int isa_irq, enum hvm_intsrc src)
-{
-    unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
-
-    if ( src == hvm_intsrc_pic )
-        return (v->domain->arch.hvm_domain.vpic[isa_irq >> 3].irq_base
-                + (isa_irq & 7));
-
-    ASSERT(src == hvm_intsrc_lapic);
-    return domain_vioapic(v->domain)->redirtbl[gsi].fields.vector;
-}
-
-int is_isa_irq_masked(struct vcpu *v, int isa_irq)
-{
-    unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
-    uint8_t pic_imr;
-
-    if ( is_lvtt(v, isa_irq) )
-        return !is_lvtt_enabled(v);
-
-    pic_imr = v->domain->arch.hvm_domain.vpic[isa_irq >> 3].imr;
-    return (((pic_imr & (1 << (isa_irq & 7))) || !vlapic_accept_pic_intr(v)) &&
-            domain_vioapic(v->domain)->redirtbl[gsi].fields.mask);
 }
 
 int hvm_local_events_need_delivery(struct vcpu *v)
diff -r 20898120c8f9 -r 4553bc1087d9 xen/arch/x86/hvm/rtc.c
--- a/xen/arch/x86/hvm/rtc.c    Wed Dec 12 12:02:01 2007 +0000
+++ b/xen/arch/x86/hvm/rtc.c    Wed Dec 12 15:41:20 2007 +0000
@@ -40,14 +40,6 @@ static void rtc_periodic_cb(struct vcpu 
     spin_lock(&s->lock);
     s->hw.cmos_data[RTC_REG_C] |= 0xc0;
     spin_unlock(&s->lock);
-}
-
-int is_rtc_periodic_irq(void *opaque)
-{
-    RTCState *s = opaque;
-
-    return !(s->hw.cmos_data[RTC_REG_C] & RTC_AF || 
-             s->hw.cmos_data[RTC_REG_C] & RTC_UF);
 }
 
 /* Enable/configure/disable the periodic timer based on the RTC_PIE and
@@ -488,6 +480,8 @@ void rtc_init(struct vcpu *v, int base)
 
     spin_lock_init(&s->lock);
 
+    s->pt.source = PTSRC_isa;
+
     s->hw.cmos_data[RTC_REG_A] = RTC_REF_CLCK_32KHZ | 6; /* ~1kHz */
     s->hw.cmos_data[RTC_REG_B] = RTC_24H;
     s->hw.cmos_data[RTC_REG_C] = 0;
diff -r 20898120c8f9 -r 4553bc1087d9 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Wed Dec 12 12:02:01 2007 +0000
+++ b/xen/arch/x86/hvm/vlapic.c Wed Dec 12 15:41:20 2007 +0000
@@ -68,9 +68,6 @@ static unsigned int vlapic_lvt_mask[VLAP
 #define APIC_DEST_NOSHORT                0x0
 #define APIC_DEST_MASK                   0x800
 
-#define vlapic_lvt_enabled(vlapic, lvt_type)                    \
-    (!(vlapic_get_reg(vlapic, lvt_type) & APIC_LVT_MASKED))
-
 #define vlapic_lvt_vector(vlapic, lvt_type)                     \
     (vlapic_get_reg(vlapic, lvt_type) & APIC_VECTOR_MASK)
 
@@ -932,6 +929,8 @@ int vlapic_init(struct vcpu *v)
 
     HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "%d", v->vcpu_id);
 
+    vlapic->pt.source = PTSRC_lapic;
+
 #ifdef __i386__
     /* 32-bit VMX may be limited to 32-bit physical addresses. */
     if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
@@ -974,15 +973,3 @@ void vlapic_destroy(struct vcpu *v)
     unmap_domain_page_global(vlapic->regs);
     free_domheap_page(vlapic->regs_page);
 }
-
-int is_lvtt(struct vcpu *v, int vector)
-{
-    return (pt_active(&vcpu_vlapic(v)->pt) &&
-            (vector == vlapic_lvt_vector(vcpu_vlapic(v), APIC_LVTT)));
-}
-
-int is_lvtt_enabled(struct vcpu *v)
-{
-    return (vlapic_enabled(vcpu_vlapic(v)) &&
-            vlapic_lvt_enabled(vcpu_vlapic(v), APIC_LVTT));
-}
diff -r 20898120c8f9 -r 4553bc1087d9 xen/arch/x86/hvm/vpt.c
--- a/xen/arch/x86/hvm/vpt.c    Wed Dec 12 12:02:01 2007 +0000
+++ b/xen/arch/x86/hvm/vpt.c    Wed Dec 12 15:41:20 2007 +0000
@@ -15,7 +15,6 @@
  * You should have received a copy of the GNU General Public License along with
  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
  */
 
 #include <xen/time.h>
@@ -25,6 +24,46 @@
 
 #define mode_is(d, name) \
     ((d)->arch.hvm_domain.params[HVM_PARAM_TIMER_MODE] == HVMPTM_##name)
+
+static int pt_irq_vector(struct periodic_time *pt, enum hvm_intsrc src)
+{
+    struct vcpu *v = pt->vcpu;
+    unsigned int gsi, isa_irq;
+
+    if ( pt->source == PTSRC_lapic )
+        return pt->irq;
+
+    isa_irq = pt->irq;
+    gsi = hvm_isa_irq_to_gsi(isa_irq);
+
+    if ( src == hvm_intsrc_pic )
+        return (v->domain->arch.hvm_domain.vpic[isa_irq >> 3].irq_base
+                + (isa_irq & 7));
+
+    ASSERT(src == hvm_intsrc_lapic);
+    return domain_vioapic(v->domain)->redirtbl[gsi].fields.vector;
+}
+
+static int pt_irq_masked(struct periodic_time *pt)
+{
+    struct vcpu *v = pt->vcpu;
+    unsigned int gsi, isa_irq;
+    uint8_t pic_imr;
+
+    if ( pt->source == PTSRC_lapic )
+    {
+        struct vlapic *vlapic = vcpu_vlapic(v);
+        return (vlapic_enabled(vlapic) &&
+                !(vlapic_get_reg(vlapic, APIC_LVTT) & APIC_LVT_MASKED));
+    }
+
+    isa_irq = pt->irq;
+    gsi = hvm_isa_irq_to_gsi(isa_irq);
+    pic_imr = v->domain->arch.hvm_domain.vpic[isa_irq >> 3].imr;
+
+    return (((pic_imr & (1 << (isa_irq & 7))) || !vlapic_accept_pic_intr(v)) &&
+            domain_vioapic(v->domain)->redirtbl[gsi].fields.mask);
+}
 
 static void pt_lock(struct periodic_time *pt)
 {
@@ -144,29 +183,39 @@ void pt_update_irq(struct vcpu *v)
 void pt_update_irq(struct vcpu *v)
 {
     struct list_head *head = &v->arch.hvm_vcpu.tm_list;
-    struct periodic_time *pt;
+    struct periodic_time *pt, *earliest_pt = NULL;
     uint64_t max_lag = -1ULL;
-    int irq = -1;
-
-    spin_lock(&v->arch.hvm_vcpu.tm_lock);
-
-    list_for_each_entry ( pt, head, list )
-    {
-        if ( !is_isa_irq_masked(v, pt->irq) && pt->pending_intr_nr &&
+    int irq, is_lapic;
+
+    spin_lock(&v->arch.hvm_vcpu.tm_lock);
+
+    list_for_each_entry ( pt, head, list )
+    {
+        if ( !pt_irq_masked(pt) && pt->pending_intr_nr &&
              ((pt->last_plt_gtime + pt->period_cycles) < max_lag) )
         {
             max_lag = pt->last_plt_gtime + pt->period_cycles;
-            irq = pt->irq;
+            earliest_pt = pt;
         }
     }
 
-    spin_unlock(&v->arch.hvm_vcpu.tm_lock);
-
-    if ( is_lvtt(v, irq) )
+    if ( earliest_pt == NULL )
+    {
+        spin_unlock(&v->arch.hvm_vcpu.tm_lock);
+        return;
+    }
+
+    earliest_pt->irq_issued = 1;
+    irq = earliest_pt->irq;
+    is_lapic = (earliest_pt->source == PTSRC_lapic);
+
+    spin_unlock(&v->arch.hvm_vcpu.tm_lock);
+
+    if ( is_lapic )
     {
         vlapic_set_irq(vcpu_vlapic(v), irq, 0);
     }
-    else if ( irq >= 0 )
+    else
     {
         hvm_isa_irq_deassert(v->domain, irq);
         hvm_isa_irq_assert(v->domain, irq);
@@ -178,29 +227,12 @@ static struct periodic_time *is_pt_irq(
 {
     struct list_head *head = &v->arch.hvm_vcpu.tm_list;
     struct periodic_time *pt;
-    struct RTCState *rtc = &v->domain->arch.hvm_domain.pl_time.vrtc;
-    int vector;
-
-    list_for_each_entry ( pt, head, list )
-    {
-        if ( !pt->pending_intr_nr )
-            continue;
-
-        if ( is_lvtt(v, pt->irq) )
-        {
-            if ( pt->irq != intack.vector )
-                continue;
+
+    list_for_each_entry ( pt, head, list )
+    {
+        if ( pt->pending_intr_nr && pt->irq_issued &&
+             (intack.vector == pt_irq_vector(pt, intack.source)) )
             return pt;
-        }
-
-        vector = get_isa_irq_vector(v, pt->irq, intack.source);
-
-        /* RTC irq need special care */
-        if ( (intack.vector != vector) ||
-             ((pt->irq == 8) && !is_rtc_periodic_irq(rtc)) )
-            continue;
-
-        return pt;
     }
 
     return NULL;
@@ -222,6 +254,7 @@ void pt_intr_post(struct vcpu *v, struct
     }
 
     pt->do_not_freeze = 0;
+    pt->irq_issued = 0;
 
     if ( pt->one_shot )
     {
@@ -291,12 +324,15 @@ void create_periodic_time(
     struct vcpu *v, struct periodic_time *pt, uint64_t period,
     uint8_t irq, char one_shot, time_cb *cb, void *data)
 {
+    ASSERT(pt->source != 0);
+
     destroy_periodic_time(pt);
 
     spin_lock(&v->arch.hvm_vcpu.tm_lock);
 
     pt->pending_intr_nr = 0;
     pt->do_not_freeze = 0;
+    pt->irq_issued = 0;
 
     /* Periodic timer must be at least 0.9ms. */
     if ( (period < 900000) && !one_shot )
@@ -319,7 +355,7 @@ void create_periodic_time(
      * LAPIC ticks for process accounting can see long sequences of process
      * ticks incorrectly accounted to interrupt processing.
      */
-    if ( is_lvtt(v, irq) )
+    if ( pt->source == PTSRC_lapic )
         pt->scheduled += period >> 1;
     pt->cb = cb;
     pt->priv = data;
diff -r 20898120c8f9 -r 4553bc1087d9 xen/include/asm-x86/hvm/irq.h
--- a/xen/include/asm-x86/hvm/irq.h     Wed Dec 12 12:02:01 2007 +0000
+++ b/xen/include/asm-x86/hvm/irq.h     Wed Dec 12 15:41:20 2007 +0000
@@ -160,7 +160,4 @@ struct hvm_intack hvm_vcpu_ack_pending_i
 struct hvm_intack hvm_vcpu_ack_pending_irq(struct vcpu *v,
                                            struct hvm_intack intack);
 
-int get_isa_irq_vector(struct vcpu *vcpu, int irq, enum hvm_intsrc src);
-int is_isa_irq_masked(struct vcpu *v, int isa_irq);
-
 #endif /* __ASM_X86_HVM_IRQ_H__ */
diff -r 20898120c8f9 -r 4553bc1087d9 xen/include/asm-x86/hvm/vlapic.h
--- a/xen/include/asm-x86/hvm/vlapic.h  Wed Dec 12 12:02:01 2007 +0000
+++ b/xen/include/asm-x86/hvm/vlapic.h  Wed Dec 12 15:41:20 2007 +0000
@@ -92,7 +92,4 @@ struct vlapic *apic_round_robin(
 
 int vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t mda);
 
-int is_lvtt(struct vcpu *v, int vector);
-int is_lvtt_enabled(struct vcpu *v);
-
 #endif /* __ASM_X86_HVM_VLAPIC_H__ */
diff -r 20898120c8f9 -r 4553bc1087d9 xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h     Wed Dec 12 12:02:01 2007 +0000
+++ b/xen/include/asm-x86/hvm/vpt.h     Wed Dec 12 15:41:20 2007 +0000
@@ -75,6 +75,10 @@ struct periodic_time {
     bool_t on_list;
     bool_t one_shot;
     bool_t do_not_freeze;
+    bool_t irq_issued;
+#define PTSRC_isa    1 /* ISA time source */
+#define PTSRC_lapic  2 /* LAPIC time source */
+    u8 source;                  /* PTSRC_ */
     u8 irq;
     struct vcpu *vcpu;          /* vcpu timer interrupt delivers to */
     u32 pending_intr_nr;        /* pending timer interrupts */
@@ -146,8 +150,10 @@ void pt_migrate(struct vcpu *v);
 
 /*
  * Create/destroy a periodic (or one-shot!) timer.
- * The given periodic timer structure must be initialised with zero bytes or
- * have been initialised by a previous invocation of create_periodic_time().
+ * The given periodic timer structure must be initialised with zero bytes,
+ * except for the 'source' field which must be initialised with the
+ * correct PTSRC_ value. The initialised timer structure can then be passed
+ * to {create,destroy}_periodic_time() and number of times and in any order.
  * Note that, for a given periodic timer, invocations of these functions MUST
  * be serialised.
  */
@@ -163,7 +169,6 @@ void rtc_init(struct vcpu *v, int base);
 void rtc_init(struct vcpu *v, int base);
 void rtc_migrate_timers(struct vcpu *v);
 void rtc_deinit(struct domain *d);
-int is_rtc_periodic_irq(void *opaque);
 void pmtimer_init(struct vcpu *v);
 void pmtimer_deinit(struct domain *d);
 

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