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] [HVM] Fix an error when read from APIC re

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [HVM] Fix an error when read from APIC registers like IRR, ISR and TMR.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 13 Sep 2006 16:30:15 +0000
Delivery-date: Wed, 13 Sep 2006 09:31:12 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
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/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/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 kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 3e31c5e160cfd01493e3e89256c733dda7efc922
# Parent  885c1513c6743cc6d8373f973a4fa696ce5215cb
[HVM] Fix an error when read from APIC registers like IRR, ISR and TMR.
>From SDM3 spec, for APIC registers, all 32-bit registers should
be accessed using 128-bit aligned 32bit loads or stores.
And wider registers (64-bit or 256-bit) must be accessed using
multiple 32-bit loads or stores.

In old APIC virtualization code, we use IRR, ISR and TMR which are
256-bit registers as contiguous bit maps other than multiple 32-bit.

So guest always fetch error values.

Original patch was:
 * Signed-off-by: Xiaohui Xin <xiaohui.xin@xxxxxxxxx>
 * Signed-off-by: Yunhong Jiang <yunhong.jiang@xxxxxxxxx>
 * Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx>

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/vlapic.c        |   35 ++++++++++++++++-------------------
 xen/include/asm-x86/hvm/vlapic.h |   30 ++++++++++++++++++++++--------
 2 files changed, 38 insertions(+), 27 deletions(-)

diff -r 885c1513c674 -r 3e31c5e160cf xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Wed Sep 13 15:15:27 2006 +0100
+++ b/xen/arch/x86/hvm/vlapic.c Wed Sep 13 15:59:14 2006 +0100
@@ -66,12 +66,10 @@ int vlapic_find_highest_irr(struct vlapi
 {
     int result;
 
-     result = find_highest_bit((unsigned long *)(vlapic->regs + APIC_IRR),
-                               MAX_VECTOR);
-
-     ASSERT( result == -1 || result >= 16);
-
-     return result;
+    result = vlapic_find_highest_vector(vlapic->regs + APIC_IRR);
+    ASSERT((result == -1) || (result >= 16));
+
+    return result;
 }
 
 s_time_t get_apictime_scheduled(struct vcpu *v)
@@ -89,10 +87,8 @@ int vlapic_find_highest_isr(struct vlapi
 {
     int result;
 
-    result = find_highest_bit((unsigned long *)(vlapic->regs + APIC_ISR),
-                               MAX_VECTOR);
-
-    ASSERT( result == -1 || result >= 16);
+    result = vlapic_find_highest_vector(vlapic->regs + APIC_ISR);
+    ASSERT((result == -1) || (result >= 16));
 
     return result;
 }
@@ -221,7 +217,8 @@ static int vlapic_accept_irq(struct vcpu
         if ( unlikely(vlapic == NULL || !vlapic_enabled(vlapic)) )
             break;
 
-        if ( test_and_set_bit(vector, vlapic->regs + APIC_IRR) && trig_mode)
+        if ( vlapic_test_and_set_vector(vector, vlapic->regs + APIC_IRR) &&
+             trig_mode)
         {
             HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
                   "level trig mode repeatedly for vector %d\n", vector);
@@ -232,7 +229,7 @@ static int vlapic_accept_irq(struct vcpu
         {
             HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
               "level trig mode for vector %d\n", vector);
-            set_bit(vector, vlapic->regs + APIC_TMR);
+            vlapic_set_vector(vector, vlapic->regs + APIC_TMR);
         }
         hvm_prod_vcpu(v);
 
@@ -358,10 +355,10 @@ void vlapic_EOI_set(struct vlapic *vlapi
     if ( vector == -1 )
         return ;
 
-    clear_bit(vector, vlapic->regs + APIC_ISR);
+    vlapic_clear_vector(vector, vlapic->regs + APIC_ISR);
     vlapic_update_ppr(vlapic);
 
-    if ( test_and_clear_bit(vector, vlapic->regs + APIC_TMR) )
+    if ( vlapic_test_and_clear_vector(vector, vlapic->regs + APIC_TMR) )
         ioapic_update_EOI(vlapic->domain, vector);
 }
 
@@ -816,7 +813,7 @@ void vlapic_timer_fn(void *data)
 
     vlapic->timer_last_update = now;
 
-    if ( test_and_set_bit(timer_vector, vlapic->regs + APIC_IRR ))
+    if ( vlapic_test_and_set_vector(timer_vector, vlapic->regs + APIC_IRR) )
         vlapic->intr_pending_count[timer_vector]++;
 
     if ( vlapic_lvtt_period(vlapic) )
@@ -893,7 +890,7 @@ int cpu_get_apic_interrupt(struct vcpu *
                 HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
                             "Sending an illegal vector 0x%x.", highest_irr);
 
-                set_bit(err_vector, vlapic->regs + APIC_IRR);
+                vlapic_set_vector(err_vector, vlapic->regs + APIC_IRR);
                 highest_irr = err_vector;
             }
 
@@ -943,15 +940,15 @@ void vlapic_post_injection(struct vcpu *
     switch ( deliver_mode ) {
     case APIC_DM_FIXED:
     case APIC_DM_LOWEST:
-        set_bit(vector, vlapic->regs + APIC_ISR);
-        clear_bit(vector, vlapic->regs + APIC_IRR);
+        vlapic_set_vector(vector, vlapic->regs + APIC_ISR);
+        vlapic_clear_vector(vector, vlapic->regs + APIC_IRR);
         vlapic_update_ppr(vlapic);
 
         if ( vector == vlapic_lvt_vector(vlapic, APIC_LVTT) )
         {
             vlapic->intr_pending_count[vector]--;
             if ( vlapic->intr_pending_count[vector] > 0 )
-                test_and_set_bit(vector, vlapic->regs + APIC_IRR);
+                vlapic_test_and_set_vector(vector, vlapic->regs + APIC_IRR);
         }
         break;
 
diff -r 885c1513c674 -r 3e31c5e160cf xen/include/asm-x86/hvm/vlapic.h
--- a/xen/include/asm-x86/hvm/vlapic.h  Wed Sep 13 15:15:27 2006 +0100
+++ b/xen/include/asm-x86/hvm/vlapic.h  Wed Sep 13 15:59:14 2006 +0100
@@ -23,12 +23,28 @@
 #include <asm/msr.h>
 #include <public/hvm/ioreq.h>
 
-static __inline__ int find_highest_bit(unsigned long *data, int nr_bits)
+#define MAX_VECTOR      256
+
+#define VEC_POS(v) ((v)%32)
+#define REG_POS(v) (((v)/32)* 0x10)
+#define vlapic_test_and_set_vector(vec, bitmap)                 \
+    test_and_set_bit(VEC_POS(vec), (bitmap) + REG_POS(vec))
+#define vlapic_test_and_clear_vector(vec, bitmap)               \
+    test_and_clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec))
+#define vlapic_set_vector(vec, bitmap)                          \
+    set_bit(VEC_POS(vec), (bitmap) + REG_POS(vec))
+#define vlapic_clear_vector(vec, bitmap)                        \
+    clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec))
+
+static inline int vlapic_find_highest_vector(u32 *bitmap)
 {
-    int length = BITS_TO_LONGS(nr_bits);
-    while ( length && !data[--length] )
+    int word_offset = MAX_VECTOR / 32;
+
+    /* Work backwards through the bitmap (first 32-bit word in every four). */
+    while ( (word_offset != 0) && (bitmap[(--word_offset)*4] == 0) )
         continue;
-    return (fls(data[length]) - 1) + (length * BITS_PER_LONG);
+
+    return (fls(bitmap[word_offset*4]) - 1) + (word_offset * 32);
 }
 
 #define VLAPIC(v)                       (v->arch.hvm_vcpu.vlapic)
@@ -83,8 +99,6 @@ typedef struct direct_intr_info {
     int source[6];
 } direct_intr_info_t;
 
-#define MAX_VECTOR      256
-
 struct vlapic {
     uint32_t           status;
     uint32_t           vcpu_id;
@@ -108,9 +122,9 @@ static inline int vlapic_set_irq(struct 
 {
     int ret;
 
-    ret = test_and_set_bit(vec, vlapic->regs + APIC_IRR);
+    ret = vlapic_test_and_set_vector(vec, vlapic->regs + APIC_IRR);
     if ( trig )
-        set_bit(vec, vlapic->regs + APIC_TMR);
+        vlapic_set_vector(vec, vlapic->regs + APIC_TMR);
 
     /* We may need to wake up target vcpu, besides set pending bit here */
     return ret;

_______________________________________________
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] [HVM] Fix an error when read from APIC registers like IRR, ISR and TMR., Xen patchbot-unstable <=