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

[Xen-changelog] [xen-unstable] [HVM] Place all APIC registers into one page in native format.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID a6cb8ba24a914854c56d002132c13649306274ec
# Parent  637b6d60e792aaebe147fc900be4d27ddeb9bf74
[HVM] Place all APIC registers into one page in native format.
With this change we can re-use code at include/asm-x86/apicdef.h,
making the code much cleaner. Also it help for future enhancement.

This patch does not change any logic except the change to
CONTROL_REG_ACCESS_NUM, which should be 0xf for CR8 access.

Signed-off-by: Yunhong Jiang <yunhong.jiang@xxxxxxxxx
---
 xen/arch/x86/hvm/i8259.c            |    4 
 xen/arch/x86/hvm/svm/intr.c         |   18 -
 xen/arch/x86/hvm/vioapic.c          |   37 +-
 xen/arch/x86/hvm/vlapic.c           |  555 ++++++++++++++++--------------------
 xen/arch/x86/hvm/vmx/io.c           |   17 -
 xen/arch/x86/hvm/vmx/vmx.c          |    2 
 xen/include/asm-ia64/vmx_platform.h |   11 
 xen/include/asm-x86/hvm/support.h   |    2 
 xen/include/asm-x86/hvm/vlapic.h    |  113 ++-----
 xen/include/asm-x86/hvm/vmx/vmx.h   |    2 
 10 files changed, 346 insertions(+), 415 deletions(-)

diff -r 637b6d60e792 -r a6cb8ba24a91 xen/arch/x86/hvm/i8259.c
--- a/xen/arch/x86/hvm/i8259.c  Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/arch/x86/hvm/i8259.c  Wed Aug 02 10:07:03 2006 +0100
@@ -590,7 +590,7 @@ int cpu_get_pic_interrupt(struct vcpu *v
 
     /* read the irq from the PIC */
     intno = pic_read_irq(s);
-    *type = VLAPIC_DELIV_MODE_EXT;
+    *type = APIC_DM_EXTINT;
     return intno;
 }
 
@@ -598,7 +598,7 @@ int is_pit_irq(struct vcpu *v, int irq, 
 {
     int pit_vec;
 
-    if (type == VLAPIC_DELIV_MODE_EXT)
+    if (type == APIC_DM_EXTINT)
         pit_vec = v->domain->arch.hvm_domain.vpic.pics[0].irq_base;
     else
         pit_vec =
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c       Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/arch/x86/hvm/svm/intr.c       Wed Aug 02 10:07:03 2006 +0100
@@ -76,7 +76,7 @@ interrupt_post_injection(struct vcpu * v
 
     switch(type)
     {
-    case VLAPIC_DELIV_MODE_EXT:
+    case APIC_DM_EXTINT:
         break;
 
     default:
@@ -112,7 +112,7 @@ asmlinkage void svm_intr_assist(void)
     struct hvm_domain *plat=&v->domain->arch.hvm_domain; 
     struct periodic_time *pt = &plat->pl_time.periodic_tm;
     struct hvm_virpic *pic= &plat->vpic;
-    int intr_type = VLAPIC_DELIV_MODE_EXT;
+    int intr_type = APIC_DM_EXTINT;
     int intr_vector = -1;
     int re_injecting = 0;
     unsigned long rflags;
@@ -172,9 +172,9 @@ asmlinkage void svm_intr_assist(void)
     /* have we got an interrupt to inject? */
     if (intr_vector >= 0) {
         switch (intr_type) {
-        case VLAPIC_DELIV_MODE_EXT:
-        case VLAPIC_DELIV_MODE_FIXED:
-        case VLAPIC_DELIV_MODE_LPRI:
+        case APIC_DM_EXTINT:
+        case APIC_DM_FIXED:
+        case APIC_DM_LOWEST:
             /* Re-injecting a PIT interruptt? */
             if (re_injecting && 
                 is_pit_irq(v, intr_vector, intr_type)) {
@@ -185,10 +185,10 @@ asmlinkage void svm_intr_assist(void)
             svm_inject_extint(v, intr_vector, VMX_DELIVER_NO_ERROR_CODE);
             interrupt_post_injection(v, intr_vector, intr_type);
             break;
-        case VLAPIC_DELIV_MODE_SMI:
-        case VLAPIC_DELIV_MODE_NMI:
-        case VLAPIC_DELIV_MODE_INIT:
-        case VLAPIC_DELIV_MODE_STARTUP:
+        case APIC_DM_SMI:
+        case APIC_DM_NMI:
+        case APIC_DM_INIT:
+        case APIC_DM_STARTUP:
         default:
             printk("Unsupported interrupt type: %d\n", intr_type);
             BUG();
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c        Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/arch/x86/hvm/vioapic.c        Wed Aug 02 10:07:03 2006 +0100
@@ -197,7 +197,7 @@ static void hvm_vioapic_write_indirect(s
                     redir_content = ((redir_content >> 32) << 32) |
                                     (val & 0xffffffff);
                 s->redirtbl[redir_index].value = redir_content;
-               hvm_vioapic_update_imr(s, redir_index);
+                hvm_vioapic_update_imr(s, redir_index);
             } else  {
                 printk("hvm_vioapic_write_indirect "
                   "error register %x\n", s->ioregsel);
@@ -295,8 +295,8 @@ static int ioapic_inj_irq(hvm_vioapic_t 
       vector, trig_mode, delivery_mode);
 
     switch (delivery_mode) {
-    case VLAPIC_DELIV_MODE_FIXED:
-    case VLAPIC_DELIV_MODE_LPRI:
+    case dest_Fixed:
+    case dest_LowestPrio:
         if (vlapic_set_irq(target, vector, trig_mode) && (trig_mode == 1))
             printk("<ioapic_inj_irq> level interrupt happen before cleared\n");
         result = 1;
@@ -314,6 +314,7 @@ static int ioapic_match_logical_addr(hvm
 static int ioapic_match_logical_addr(hvm_vioapic_t *s, int number, uint8_t 
dest)
 {
     int result = 0;
+    uint32_t logical_dest = vlapic_get_reg(s->lapic_info[number], APIC_LDR);
 
     ASSERT(s && s->lapic_info[number]);
 
@@ -321,17 +322,17 @@ static int ioapic_match_logical_addr(hvm
       "number %i dest %x\n",
       number, dest);
 
-    switch (((s->lapic_info[number]->dest_format >> 28) & 0xf)) {
-    case 0xf:
+    switch (vlapic_get_reg(s->lapic_info[number], APIC_DFR))
+    {
+    case APIC_DFR_FLAT:
         result =
-          (dest & ((s->lapic_info[number]->logical_dest >> 24) & 0xff)) != 0;
-        break;
-    case 0x0:
+          (dest & GET_APIC_LOGICAL_ID(logical_dest)) != 0;
+        break;
+    case APIC_DFR_CLUSTER:
         /* Should we support flat cluster mode ?*/
-        if ( ((s->lapic_info[number]->logical_dest >> 28)
+        if ( (GET_APIC_LOGICAL_ID(logical_dest) >> 4
                == ((dest >> 0x4) & 0xf)) &&
-             (((s->lapic_info[number]->logical_dest >> 24) & 0xf)
-               & (dest  & 0xf)) )
+             (logical_dest & (dest  & 0xf)) )
             result = 1;
         break;
     default:
@@ -410,7 +411,7 @@ static void ioapic_deliver(hvm_vioapic_t
     }
 
     switch (delivery_mode) {
-    case VLAPIC_DELIV_MODE_LPRI:
+    case dest_LowestPrio:
     {
         struct vlapic* target;
 
@@ -430,8 +431,8 @@ static void ioapic_deliver(hvm_vioapic_t
         break;
     }
 
-    case VLAPIC_DELIV_MODE_FIXED:
-    case VLAPIC_DELIV_MODE_EXT:
+    case dest_Fixed:
+    case dest_ExtINT:
     {
         uint8_t bit;
         for (bit = 0; bit < s->lapic_count; bit++) {
@@ -452,10 +453,10 @@ static void ioapic_deliver(hvm_vioapic_t
         break;
     }
 
-    case VLAPIC_DELIV_MODE_SMI:
-    case VLAPIC_DELIV_MODE_NMI:
-    case VLAPIC_DELIV_MODE_INIT:
-    case VLAPIC_DELIV_MODE_STARTUP:
+    case dest_SMI:
+    case dest_NMI:
+    case dest_INIT:
+    case dest__reserved_2:
     default:
         printk("Not support delivey mode %d\n", delivery_mode);
         break;
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/arch/x86/hvm/vlapic.c Wed Aug 02 10:07:03 2006 +0100
@@ -43,35 +43,43 @@ extern u32 get_apic_bus_cycle(void);
 
 static unsigned int vlapic_lvt_mask[VLAPIC_LVT_NUM] =
 {
-    0x310ff, 0x117ff, 0x117ff, 0x1f7ff, 0x1f7ff, 0x117ff
+     /* LVTT */
+     LVT_MASK | APIC_LVT_TIMER_PERIODIC,
+     /* LVTTHMR */
+     LVT_MASK | APIC_MODE_MASK,
+     /* LVTPC */
+     LVT_MASK | APIC_MODE_MASK,
+     /* LVT0-1 */
+     LINT_MASK, LINT_MASK,
+     /* LVTERR */
+     LVT_MASK
 };
 
+int hvm_apic_support(struct domain *d)
+{
+    return d->arch.hvm_domain.apic_enabled;
+}
+
 int vlapic_find_highest_irr(struct vlapic *vlapic)
 {
     int result;
 
-    result = find_highest_bit(vlapic->irr, MAX_VECTOR);
-
-    if ( result != -1 && result < 16 )
-    {
-        printk("VLAPIC: irr on reserved bits %d\n ", result);
-        domain_crash_synchronous();
-    }
-
-    return result;
-}
-
-int hvm_apic_support(struct domain *d)
-{
-    return d->arch.hvm_domain.apic_enabled;
+     result = find_highest_bit((unsigned long *)(vlapic->regs + APIC_IRR),
+                               MAX_VECTOR);
+
+     ASSERT( result == -1 || result > 16);
+
+     return result;
 }
 
 s_time_t get_apictime_scheduled(struct vcpu *v)
 {
     struct vlapic *vlapic = VLAPIC(v);
 
-    if ( !hvm_apic_support(v->domain) || !vlapic_lvt_timer_enabled(vlapic) )
+    if ( !hvm_apic_support(v->domain) ||
+         !vlapic_lvt_enabled(vlapic, APIC_LVTT) )
         return -1;
+
     return vlapic->vlapic_timer.expires;
 }
 
@@ -79,16 +87,10 @@ int vlapic_find_highest_isr(struct vlapi
 {
     int result;
 
-    result = find_highest_bit(vlapic->isr, MAX_VECTOR);
-
-    if ( result != -1 && result < 16 )
-    {
-        int i = 0;
-        printk("VLAPIC: isr on reserved bits %d, isr is\n ", result);
-        for ( i = 0; i < ARRAY_SIZE(vlapic->isr); i++ )
-            printk("%d: %p\n", i, (void *)vlapic->isr[i]);
-        return -1;
-    }
+    result = find_highest_bit((unsigned long *)(vlapic->regs + APIC_ISR),
+                               MAX_VECTOR);
+
+    ASSERT( result == -1 || result > 16);
 
     return result;
 }
@@ -98,20 +100,21 @@ uint32_t vlapic_update_ppr(struct vlapic
     uint32_t tpr, isrv, ppr;
     int isr;
 
-    tpr = (vlapic->task_priority >> 4) & 0xf;      /* we want 7:4 */
+    tpr = vlapic_get_reg(vlapic, APIC_TASKPRI);
 
     isr = vlapic_find_highest_isr(vlapic);
+
     if ( isr != -1 )
         isrv = (isr >> 4) & 0xf;   /* ditto */
     else
         isrv = 0;
 
-    if ( tpr >= isrv )
-        ppr = vlapic->task_priority & 0xff;
+    if ( (tpr >> 4) >= isrv )
+        ppr = tpr & 0xff;
     else
         ppr = isrv << 4;  /* low 4 bits of PPR have to be cleared */
 
-    vlapic->processor_priority = ppr;
+    vlapic_set_reg(vlapic, APIC_PROCPRI, ppr);
 
     HVM_DBG_LOG(DBG_LEVEL_VLAPIC_INTERRUPT,
                 "vlapic %p, ppr 0x%x, isr 0x%x, isrv 0x%x.",
@@ -133,9 +136,9 @@ static int vlapic_match_dest(struct vcpu
                 target, source, dest, dest_mode, short_hand, delivery_mode);
 
     if ( unlikely(target == NULL) &&
-         ((delivery_mode != VLAPIC_DELIV_MODE_INIT) &&
-          (delivery_mode != VLAPIC_DELIV_MODE_STARTUP) &&
-          (delivery_mode != VLAPIC_DELIV_MODE_NMI)) )
+         ((delivery_mode != APIC_DM_INIT) &&
+          (delivery_mode != APIC_DM_STARTUP) &&
+          (delivery_mode != APIC_DM_NMI)) )
     {
         HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "uninitialized target vcpu %p, "
                     "delivery_mode 0x%x, dest 0x%x.\n", v, delivery_mode, 
dest);
@@ -143,22 +146,27 @@ static int vlapic_match_dest(struct vcpu
     }
 
     switch ( short_hand ) {
-    case VLAPIC_NO_SHORTHAND:
+    case APIC_DEST_NOSHORT:             /* no shorthand */
         if ( !dest_mode )   /* Physical */
         {
-            result = (target != NULL ? target->id : v->vcpu_id) == dest;
+            result = ( ((target != NULL) ?
+                         GET_APIC_ID(vlapic_get_reg(target, APIC_ID)):
+                         v->vcpu_id)) == dest;
         }
         else                /* Logical */
         {
+            uint32_t ldr = vlapic_get_reg(target, APIC_LDR);
+
             if ( target == NULL )
                 break;
-            if ( ((target->dest_format >> 28) & 0xf) == 0xf )   /* Flat mode */
+            /* Flat mode */
+            if ( vlapic_get_reg(target, APIC_DFR) == APIC_DFR_FLAT)
             {
-                result = (target->logical_dest >> 24) & dest;
+                result = GET_APIC_LOGICAL_ID(ldr) & dest;
             }
             else
             {
-                if ( (delivery_mode == VLAPIC_DELIV_MODE_LPRI) &&
+                if ( (delivery_mode == APIC_DM_LOWEST) &&
                      (dest == 0xff) )
                 {
                     /* What shall we do now? */
@@ -166,22 +174,22 @@ static int vlapic_match_dest(struct vcpu
                            "delivery mode\n");
                     domain_crash_synchronous();
                 }
-                result = (target->logical_dest == (dest & 0xf)) ?
-                         ((target->logical_dest >> 4) & (dest >> 4)) : 0;
+                result = (GET_APIC_LOGICAL_ID(ldr) == (dest & 0xf)) ?
+                         (GET_APIC_LOGICAL_ID(ldr) >> 4) & (dest >> 4) : 0;
             }
         }
         break;
 
-    case VLAPIC_SHORTHAND_SELF:
+    case APIC_DEST_SELF:
         if ( target == source )
             result = 1;
         break;
 
-    case VLAPIC_SHORTHAND_INCLUDE_SELF:
+    case APIC_DEST_ALLINC:
         result = 1;
         break;
 
-    case VLAPIC_SHORTHAND_EXCLUDE_SELF:
+    case APIC_DEST_ALLBUT:
         if ( target != source )
             result = 1;
         break;
@@ -204,13 +212,13 @@ static int vlapic_accept_irq(struct vcpu
     struct vlapic *vlapic = VLAPIC(v);
 
     switch ( delivery_mode ) {
-    case VLAPIC_DELIV_MODE_FIXED:
-    case VLAPIC_DELIV_MODE_LPRI:
+    case APIC_DM_FIXED:
+    case APIC_DM_LOWEST:
         /* FIXME add logic for vcpu on reset */
         if ( unlikely(vlapic == NULL || !vlapic_enabled(vlapic)) )
             break;
 
-        if ( test_and_set_bit(vector, &vlapic->irr[0]) && level)
+        if ( test_and_set_bit(vector, vlapic->regs + APIC_IRR) )
         {
             HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
               "level trig mode repeatedly for vector %d\n", vector);
@@ -221,25 +229,25 @@ 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->tmr[0]);
+            set_bit(vector, vlapic->regs + APIC_TMR);
         }
         evtchn_set_pending(v, iopacket_port(v));
 
         result = 1;
         break;
 
-    case VLAPIC_DELIV_MODE_RESERVED:
+    case APIC_DM_REMRD:
         printk("Ignore deliver mode 3 in vlapic_accept_irq\n");
         break;
 
-    case VLAPIC_DELIV_MODE_SMI:
-    case VLAPIC_DELIV_MODE_NMI:
+    case APIC_DM_SMI:
+    case APIC_DM_NMI:
         /* Fixme */
         printk("TODO: for guest SMI/NMI\n");
         break;
 
-    case VLAPIC_DELIV_MODE_INIT:
-        if ( !level && trig_mode == 1 )     //Deassert
+    case APIC_DM_INIT:
+        if ( level && !(trig_mode & APIC_INT_ASSERT) )     //Deassert
             printk("This hvm_vlapic is for P4, no work for De-assert init\n");
         else
         {
@@ -255,7 +263,7 @@ static int vlapic_accept_irq(struct vcpu
         }
         break;
 
-    case VLAPIC_DELIV_MODE_STARTUP:
+    case APIC_DM_STARTUP:
         if ( v->arch.hvm_vcpu.init_sipi_sipi_state ==
                 HVM_VCPU_INIT_SIPI_SIPI_STATE_NORM )
             break;
@@ -346,22 +354,23 @@ void vlapic_EOI_set(struct vlapic *vlapi
     if ( vector == -1 )
         return ;
 
-    clear_bit(vector, &vlapic->isr[0]);
+    clear_bit(vector, vlapic->regs + APIC_ISR);
     vlapic_update_ppr(vlapic);
 
-    if ( test_and_clear_bit(vector, &vlapic->tmr[0]) )
+    if ( test_and_clear_bit(vector, vlapic->regs + APIC_TMR) )
         ioapic_update_EOI(vlapic->domain, vector);
 }
 
-int vlapic_check_vector(struct vlapic *vlapic,
-                        unsigned char dm, int vector)
-{
-    if ( (dm == VLAPIC_DELIV_MODE_FIXED) && (vector < 16) )
+static int vlapic_check_vector(struct vlapic *vlapic,
+                        uint32_t dm, uint32_t vector)
+{
+    if ( (dm == APIC_DM_FIXED) && (vector < 16) )
     {
         vlapic->err_status |= 0x40;
-        vlapic_accept_irq(vlapic->vcpu, VLAPIC_DELIV_MODE_FIXED,
-                          vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR), 0, 0);
-        printk("<vlapic_check_vector>: check failed.\n");
+        vlapic_accept_irq(vlapic->vcpu, APIC_DM_FIXED,
+                          vlapic_lvt_vector(vlapic, APIC_LVTERR), 0, 0);
+        printk("<vlapic_check_vector>: check failed "
+               " dm %x vector %x\n", dm, vector);
         return 0;
     }
     return 1;
@@ -369,13 +378,16 @@ int vlapic_check_vector(struct vlapic *v
 
 void vlapic_ipi(struct vlapic *vlapic)
 {
-    unsigned int dest = (vlapic->icr_high >> 24) & 0xff;
-    unsigned int short_hand = (vlapic->icr_low >> 18) & 3;
-    unsigned int trig_mode = (vlapic->icr_low >> 15) & 1;
-    unsigned int level = (vlapic->icr_low >> 14) & 1;
-    unsigned int dest_mode = (vlapic->icr_low >> 11) & 1;
-    unsigned int delivery_mode = (vlapic->icr_low >> 8) & 7;
-    unsigned int vector = (vlapic->icr_low & 0xff);
+    uint32_t icr_low = vlapic_get_reg(vlapic, APIC_ICR);
+    uint32_t icr_high = vlapic_get_reg(vlapic, APIC_ICR2);
+
+    unsigned int dest =         GET_APIC_DEST_FIELD(icr_high);
+    unsigned int short_hand =   icr_low & APIC_SHORT_MASK;
+    unsigned int trig_mode =    icr_low & APIC_INT_ASSERT;
+    unsigned int level =        icr_low & APIC_INT_LEVELTRIG;
+    unsigned int dest_mode =    icr_low & APIC_DEST_MASK;
+    unsigned int delivery_mode =    icr_low & APIC_MODE_MASK;
+    unsigned int vector =       icr_low & APIC_VECTOR_MASK;
 
     struct vlapic *target;
     struct vcpu *v = NULL;
@@ -384,7 +396,7 @@ void vlapic_ipi(struct vlapic *vlapic)
     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.",
-                vlapic->icr_high, vlapic->icr_low, short_hand, dest,
+                icr_high, icr_low, short_hand, dest,
                 trig_mode, level, dest_mode, delivery_mode, vector);
 
     for_each_vcpu ( vlapic->domain, v )
@@ -392,7 +404,7 @@ void vlapic_ipi(struct vlapic *vlapic)
         if ( vlapic_match_dest(v, vlapic, short_hand,
                                dest, dest_mode, delivery_mode) )
         {
-            if ( delivery_mode == VLAPIC_DELIV_MODE_LPRI )
+            if ( delivery_mode == APIC_DM_LOWEST)
                 set_bit(v->vcpu_id, &lpr_map);
             else
                 vlapic_accept_irq(v, delivery_mode,
@@ -400,7 +412,7 @@ void vlapic_ipi(struct vlapic *vlapic)
         }
     }
 
-    if ( delivery_mode == VLAPIC_DELIV_MODE_LPRI )
+    if ( delivery_mode == APIC_DM_LOWEST)
     {
         v = vlapic->vcpu;
         target = apic_round_robin(v->domain, dest_mode, vector, lpr_map);
@@ -411,158 +423,73 @@ void vlapic_ipi(struct vlapic *vlapic)
     }
 }
 
+static uint32_t vlapic_get_tmcct(struct vlapic *vlapic)
+{
+    uint32_t counter_passed;
+    s_time_t passed, now = NOW();
+    uint32_t tmcct = vlapic_get_reg(vlapic, APIC_TMCCT);
+
+    ASSERT(vlapic != NULL);
+
+    if ( unlikely(now <= vlapic->timer_last_update) )
+    {
+        passed = ~0x0LL - vlapic->timer_last_update + now;
+        HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "time elapsed.");
+    }
+    else
+        passed = now - vlapic->timer_last_update;
+
+    counter_passed = passed /
+      (APIC_BUS_CYCLE_NS * vlapic->timer_divide_count);
+
+    tmcct -= counter_passed;
+
+    if ( tmcct <= 0 )
+    {
+        if ( unlikely(!vlapic_lvtt_period(vlapic)) )
+        {
+            tmcct =  0;
+            // FIXME: should we add interrupt here?
+        }
+        else
+        {
+            do {
+                tmcct += vlapic_get_reg(vlapic, APIC_TMICT);
+            } while ( tmcct < 0 );
+        }
+    }
+
+    vlapic->timer_last_update = now;
+    vlapic_set_reg(vlapic, APIC_TMCCT, tmcct);
+
+    HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER,
+      "timer initial count 0x%x, timer current count 0x%x, "
+      "update 0x%016"PRIx64", now 0x%016"PRIx64", offset 0x%x.",
+      vlapic_get_reg(vlapic, APIC_TMICT),
+      vlapic_get_reg(vlapic, APIC_TMCCT),
+      vlapic->timer_last_update, now, counter_passed);
+
+    return tmcct;
+}
+
 static void vlapic_read_aligned(struct vlapic *vlapic, unsigned int offset,
                          unsigned int len, unsigned int *result)
 {
-    if ( len != 4 )
-        printk("<vlapic_read_aligned> read with len=%d (should be 4).\n", len);
+    ASSERT(len == 4 && offset > 0 && offset <= APIC_TDCR);
 
     *result = 0;
 
     switch ( offset ) {
-    case APIC_ID:
-        *result = vlapic->id << 24;
-        break;
-
-    case APIC_LVR:
-        *result = vlapic->version;
-        break;
-
-    case APIC_TASKPRI:
-        *result = vlapic->task_priority;
-        break;
-
     case APIC_ARBPRI:
         printk("access local APIC ARBPRI register which is for P6\n");
         break;
 
-    case APIC_PROCPRI:
-        *result = vlapic->processor_priority;
-        break;
-
-    case APIC_EOI:      /* EOI is write only */
-        break;
-
-    case APIC_LDR:
-        *result = vlapic->logical_dest;
-        break;
-
-    case APIC_DFR:
-        *result = vlapic->dest_format;
-        break;
-
-    case APIC_SPIV:
-        *result = vlapic->spurious_vec;
-        break;
-
-    case APIC_ISR:
-    case 0x110:
-    case 0x120:
-    case 0x130:
-    case 0x140:
-    case 0x150:
-    case 0x160:
-    case 0x170:
-        *result = vlapic->isr[(offset - APIC_ISR) >> 4];
-        break;
-
-    case APIC_TMR:
-    case 0x190:
-    case 0x1a0:
-    case 0x1b0:
-    case 0x1c0:
-    case 0x1d0:
-    case 0x1e0:
-    case 0x1f0:
-        *result = vlapic->tmr[(offset - APIC_TMR) >> 4];
-        break;
-
-    case APIC_IRR:
-    case 0x210:
-    case 0x220:
-    case 0x230:
-    case 0x240:
-    case 0x250:
-    case 0x260:
-    case 0x270:
-        *result = vlapic->irr[(offset - APIC_IRR) >> 4];
-        break;
-
-    case APIC_ESR:
-        if ( vlapic->err_write_count )
-            *result = vlapic->err_status;
-        break;
-
-    case APIC_ICR:
-        *result = vlapic->icr_low;
-        break;
-
-    case APIC_ICR2:
-        *result = vlapic->icr_high;
-        break;
-
-    case APIC_LVTT:         /* LVT Timer Reg */
-    case APIC_LVTTHMR:      /* LVT Thermal Monitor */
-    case APIC_LVTPC:        /* LVT Performance Counter */
-    case APIC_LVT0:         /* LVT LINT0 Reg */
-    case APIC_LVT1:         /* LVT Lint1 Reg */
-    case APIC_LVTERR:       /* LVT Error Reg */
-        *result = vlapic->lvt[(offset - APIC_LVTT) >> 4];
-        break;
-
-    case APIC_TMICT:
-        *result = vlapic->timer_initial_count;
-        break;
-
     case APIC_TMCCT:        //Timer CCR
-        {
-            uint32_t counter_passed;
-            s_time_t passed, now = NOW();
-
-            if ( unlikely(now <= vlapic->timer_current_update) )
-            {
-                passed = ~0x0LL - vlapic->timer_current_update + now;
-                HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "time elapsed.");
-            }
-            else
-                passed = now - vlapic->timer_current_update;
-
-            counter_passed = passed /
-                             (APIC_BUS_CYCLE_NS * vlapic->timer_divide_count);
-            vlapic->timer_current_count -= counter_passed;
-            if ( vlapic->timer_current_count <= 0 )
-            {
-                if ( unlikely(!vlapic_lvt_timer_period(vlapic)) )
-                {
-                    vlapic->timer_current_count = 0;
-                    // FIXME: should we add interrupt here?
-                }
-                else
-                {
-                    do {
-                        vlapic->timer_current_count += 
vlapic->timer_initial_count;
-                    } while ( vlapic->timer_current_count < 0 );
-                }
-            }
-
-            *result = vlapic->timer_current_count;
-            vlapic->timer_current_update = now;
-
-            HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER,
-                        "timer initial count 0x%x, timer current count 0x%x, "
-                        "update 0x%016"PRIx64", now 0x%016"PRIx64", offset 
0x%x.",
-                        vlapic->timer_initial_count, 
vlapic->timer_current_count,
-                        vlapic->timer_current_update, now, counter_passed);
-        }
-        break;
-
-    case APIC_TDCR:
-        *result = vlapic->timer_divconf;
+        *result = vlapic_get_tmcct(vlapic);
         break;
 
     default:
-        printk("Read local APIC address 0x%x not implemented\n", offset);
-        *result = 0;
+        *result = vlapic_get_reg(vlapic, offset);
         break;
     }
 }
@@ -575,6 +502,9 @@ static unsigned long vlapic_read(struct 
     unsigned long result;
     struct vlapic *vlapic = VLAPIC(v);
     unsigned int offset = address - vlapic->base_address;
+
+    if ( offset > APIC_TDCR)
+        return 0;
 
     /* some bugs on kernel cause read this with byte*/
     if ( len != 4 )
@@ -671,11 +601,11 @@ static void vlapic_write(struct vcpu *v,
 
     switch ( offset ) {
     case APIC_ID:   /* Local APIC ID */
-        vlapic->id = ((val) >> 24) & VAPIC_ID_MASK;
+        vlapic_set_reg(vlapic, APIC_ID, val);
         break;
 
     case APIC_TASKPRI:
-        vlapic->task_priority = val & 0xff;
+        vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff);
         vlapic_update_ppr(vlapic);
         break;
 
@@ -684,24 +614,41 @@ static void vlapic_write(struct vcpu *v,
         break;
 
     case APIC_LDR:
-        vlapic->logical_dest = val & VAPIC_LDR_MASK;
+        vlapic_set_reg(vlapic, APIC_LDR, val & APIC_LDR_MASK);
         break;
 
     case APIC_DFR:
-        vlapic->dest_format = val ;
+        vlapic_set_reg(vlapic, APIC_DFR, val);
         break;
 
     case APIC_SPIV:
-        vlapic->spurious_vec = val & 0x1ff;
-        if ( !(vlapic->spurious_vec & 0x100) )
+        vlapic_set_reg(vlapic, APIC_SPIV, val & 0x1ff);
+
+        if ( !( val & APIC_SPIV_APIC_ENABLED) )
         {
             int i;
+            uint32_t lvt_val;
+
+            vlapic->status |= VLAPIC_SOFTWARE_DISABLE_MASK;
+
             for ( i = 0; i < VLAPIC_LVT_NUM; i++ )
-                vlapic->lvt[i] |= 0x10000;
-            vlapic->status |= VLAPIC_SOFTWARE_DISABLE_MASK;
+            {
+                lvt_val = vlapic_get_reg(vlapic, APIC_LVT1 + 0x10 * i);
+                vlapic_set_reg(vlapic, APIC_LVTT + 0x10 * i,
+                               lvt_val | APIC_LVT_MASKED);
+            }
+
+            if ( (vlapic_get_reg(vlapic, APIC_LVT0) & APIC_MODE_MASK)
+                 == APIC_DM_EXTINT )
+                clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
         }
         else
+        {
             vlapic->status &= ~VLAPIC_SOFTWARE_DISABLE_MASK;
+            if ( (vlapic_get_reg(vlapic, APIC_LVT0) & APIC_MODE_MASK)
+                  == APIC_DM_EXTINT )
+                set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
+        }
         break;
 
     case APIC_ESR:
@@ -712,12 +659,12 @@ static void vlapic_write(struct vcpu *v,
 
     case APIC_ICR:
         /* No delay here, so we always clear the pending bit*/
-        vlapic->icr_low = val & ~(1 << 12);
+        vlapic_set_reg(vlapic, APIC_ICR, val & ~(1 << 12));
         vlapic_ipi(vlapic);
         break;
 
     case APIC_ICR2:
-        vlapic->icr_high = val & 0xff000000;
+        vlapic_set_reg(vlapic, APIC_ICR2, val & 0xff000000);
         break;
 
     case APIC_LVTT:         // LVT Timer Reg
@@ -727,26 +674,25 @@ static void vlapic_write(struct vcpu *v,
     case APIC_LVT1:         // LVT Lint1 Reg
     case APIC_LVTERR:       // LVT Error Reg
         {
-            int vt = (offset - APIC_LVTT) >> 4;
-
-            vlapic->lvt[vt] = val & vlapic_lvt_mask[vt];
             if ( vlapic->status & VLAPIC_SOFTWARE_DISABLE_MASK )
-                vlapic->lvt[vt] |= VLAPIC_LVT_BIT_MASK;
+                val |= APIC_LVT_MASKED;
+
+            val &= vlapic_lvt_mask[(offset - APIC_LVTT) >> 4];
+
+            vlapic_set_reg(vlapic, offset, val);
 
             /* On hardware, when write vector less than 0x20 will error */
-            vlapic_check_vector(vlapic, vlapic_lvt_dm(vlapic->lvt[vt]),
-                                vlapic_lvt_vector(vlapic, vt));
+            if ( !(val & APIC_LVT_MASKED) )
+                vlapic_check_vector(vlapic, vlapic_lvt_dm(vlapic, offset),
+                                    vlapic_lvt_vector(vlapic, offset));
 
             if ( !vlapic->vcpu_id && (offset == APIC_LVT0) )
             {
-                if ( (vlapic->lvt[VLAPIC_LVT_LINT0] & VLAPIC_LVT_BIT_DELIMOD)
-                      == 0x700 )
-                {
-                    if ( vlapic->lvt[VLAPIC_LVT_LINT0] & VLAPIC_LVT_BIT_MASK )
+                if ( (val & APIC_MODE_MASK) == APIC_DM_EXTINT )
+                    if ( val & APIC_LVT_MASKED)
                         clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
                     else
                         set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
-                }
                 else
                     clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
             }
@@ -758,16 +704,14 @@ static void vlapic_write(struct vcpu *v,
         {
             s_time_t now = NOW(), offset;
 
-            if ( vlapic_timer_active(vlapic) )
-                stop_timer(&vlapic->vlapic_timer);
-
-            vlapic->timer_initial_count = val;
-            vlapic->timer_current_count = val;
-            vlapic->timer_current_update = now;
+            stop_timer(&vlapic->vlapic_timer);
+
+            vlapic_set_reg(vlapic, APIC_TMICT, val);
+            vlapic_set_reg(vlapic, APIC_TMCCT, val);
+            vlapic->timer_last_update = now;
 
             offset = APIC_BUS_CYCLE_NS *
-                     vlapic->timer_divide_count *
-                     vlapic->timer_initial_count;
+                     vlapic->timer_divide_count * val;
 
             set_timer(&vlapic->vlapic_timer, now + offset);
 
@@ -775,7 +719,8 @@ static void vlapic_write(struct vcpu *v,
                         "bus cycle is %"PRId64"ns, now 0x%016"PRIx64", "
                         "timer initial count 0x%x, offset 0x%016"PRIx64", "
                         "expire @ 0x%016"PRIx64".",
-                        APIC_BUS_CYCLE_NS, now, vlapic->timer_initial_count,
+                        APIC_BUS_CYCLE_NS, now,
+                        vlapic_get_reg(vlapic, APIC_TMICT),
                         offset, now + offset);
         }
         break;
@@ -787,6 +732,8 @@ static void vlapic_write(struct vcpu *v,
             tmp1 = val & 0xf;
             tmp2 = ((tmp1 & 0x3) | ((tmp1 & 0x8) >> 1)) + 1;
             vlapic->timer_divide_count = 0x1 << (tmp2 & 0x7);
+
+            vlapic_set_reg(vlapic, APIC_TDCR, val);
 
             HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, "timer divide count is 0x%x",
                         vlapic->timer_divide_count);
@@ -827,19 +774,18 @@ void vlapic_msr_set(struct vlapic *vlapi
         value &= ~MSR_IA32_APICBASE_BSP;
 
     vlapic->apic_base_msr = value;
-    vlapic->base_address = vlapic_get_base_address(vlapic);
-
-    if ( !(value & 0x800) )
+    vlapic->base_address = vlapic->apic_base_msr &
+                           MSR_IA32_APICBASE_BASE;
+
+    /* with FSB delivery interrupt, we can restart APIC functionality */
+    if ( !(value & MSR_IA32_APICBASE_ENABLE) )
         set_bit(_VLAPIC_GLOB_DISABLE, &vlapic->status );
+    else
+        clear_bit(_VLAPIC_GLOB_DISABLE, &vlapic->status);
 
     HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
                 "apic base msr is 0x%016"PRIx64", and base address is 0x%lx.",
                 vlapic->apic_base_msr, vlapic->base_address);
-}
-
-static inline int vlapic_get_init_id(struct vcpu *v)
-{
-    return v->vcpu_id;
 }
 
 void vlapic_timer_fn(void *data)
@@ -850,31 +796,32 @@ void vlapic_timer_fn(void *data)
     s_time_t now;
 
     if ( unlikely(!vlapic_enabled(vlapic) ||
-                  !vlapic_lvt_timer_enabled(vlapic)) )
+                  !vlapic_lvt_enabled(vlapic, APIC_LVTT)) )
         return;
 
     v = vlapic->vcpu;
-    timer_vector = vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER);
+    timer_vector = vlapic_lvt_vector(vlapic, APIC_LVTT);
     now = NOW();
 
-    vlapic->timer_current_update = now;
-
-    if ( test_and_set_bit(timer_vector, &vlapic->irr[0]) )
+    vlapic->timer_last_update = now;
+
+    if ( test_and_set_bit(timer_vector, vlapic->regs + APIC_IRR ))
         vlapic->intr_pending_count[timer_vector]++;
 
-    if ( vlapic_lvt_timer_period(vlapic) )
+    if ( vlapic_lvtt_period(vlapic) )
     {
         s_time_t offset;
-
-        vlapic->timer_current_count = vlapic->timer_initial_count;
+        uint32_t tmict = vlapic_get_reg(vlapic, APIC_TMICT);
+
+        vlapic_set_reg(vlapic, APIC_TMCCT, tmict);
 
         offset = APIC_BUS_CYCLE_NS *
-                 vlapic->timer_divide_count *
-                 vlapic->timer_initial_count;
+                 vlapic->timer_divide_count * tmict;
+
         set_timer(&vlapic->vlapic_timer, now + offset);
     }
     else
-        vlapic->timer_current_count = 0;
+        vlapic_set_reg(vlapic, APIC_TMCCT, 0);
 
 #if 0
     if ( test_bit(_VCPUF_running, &v->vcpu_flags) )
@@ -887,8 +834,8 @@ void vlapic_timer_fn(void *data)
                 "now 0x%016"PRIx64", expire @ 0x%016"PRIx64", "
                 "timer initial count 0x%x, timer current count 0x%x.",
                 now, vlapic->vlapic_timer.expires,
-                vlapic->timer_initial_count,
-                vlapic->timer_current_count);
+                vlapic_get_reg(vlapic, APIC_TMICT),
+                vlapic_get_reg(vlapic, APIC_TMCCT));
 }
 
 #if 0
@@ -923,23 +870,23 @@ int cpu_get_apic_interrupt(struct vcpu *
         int highest_irr = vlapic_find_highest_irr(vlapic);
 
         if ( highest_irr != -1 &&
-             ( (highest_irr & 0xF0) > vlapic->processor_priority ) )
+             ( (highest_irr & 0xF0) > vlapic_get_reg(vlapic, APIC_PROCPRI) ) )
         {
             if ( highest_irr < 0x10 )
             {
                 uint32_t err_vector;
 
                 vlapic->err_status |= 0x20;
-                err_vector = vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR);
+                err_vector = vlapic_lvt_vector(vlapic, APIC_LVTERR);
 
                 HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
                             "Sending an illegal vector 0x%x.", highest_irr);
 
-                set_bit(err_vector, &vlapic->irr[0]);
+                set_bit(err_vector, vlapic->regs + APIC_IRR);
                 highest_irr = err_vector;
             }
 
-            *mode = VLAPIC_DELIV_MODE_FIXED;
+            *mode = APIC_DM_FIXED;
             return highest_irr;
         }
     }
@@ -954,7 +901,7 @@ int cpu_has_apic_interrupt(struct vcpu* 
         int highest_irr = vlapic_find_highest_irr(vlapic);
 
         if ( highest_irr != -1 &&
-             ( (highest_irr & 0xF0) > vlapic->processor_priority ) ) {
+             ( (highest_irr & 0xF0) > vlapic_get_reg(vlapic, APIC_PROCPRI) ) ) 
{
             return 1;
         }
     }
@@ -969,30 +916,30 @@ void vlapic_post_injection(struct vcpu *
         return;
 
     switch ( deliver_mode ) {
-    case VLAPIC_DELIV_MODE_FIXED:
-    case VLAPIC_DELIV_MODE_LPRI:
-        set_bit(vector, &vlapic->isr[0]);
-        clear_bit(vector, &vlapic->irr[0]);
+    case APIC_DM_FIXED:
+    case APIC_DM_LOWEST:
+        set_bit(vector, vlapic->regs + APIC_ISR);
+        clear_bit(vector, vlapic->regs + APIC_IRR);
         vlapic_update_ppr(vlapic);
 
-        if ( vector == vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER) )
+        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->irr[0]);
+                test_and_set_bit(vector, vlapic->regs + APIC_IRR);
         }
         break;
 
     /*XXX deal with these later */
-    case VLAPIC_DELIV_MODE_RESERVED:
+    case APIC_DM_REMRD:
         printk("Ignore deliver mode 3 in vlapic_post_injection\n");
         break;
 
-    case VLAPIC_DELIV_MODE_SMI:
-    case VLAPIC_DELIV_MODE_NMI:
-    case VLAPIC_DELIV_MODE_INIT:
-    case VLAPIC_DELIV_MODE_STARTUP:
-        vlapic->direct_intr.deliver_mode &= ~(1 << deliver_mode);
+    case APIC_DM_SMI:
+    case APIC_DM_NMI:
+    case APIC_DM_INIT:
+    case APIC_DM_STARTUP:
+        vlapic->direct_intr.deliver_mode &= deliver_mode;
         break;
 
     default:
@@ -1004,7 +951,7 @@ static int vlapic_reset(struct vlapic *v
 static int vlapic_reset(struct vlapic *vlapic)
 {
     struct vcpu *v;
-    int apic_id, i;
+    int i;
 
     ASSERT( vlapic != NULL );
 
@@ -1012,29 +959,28 @@ static int vlapic_reset(struct vlapic *v
 
     ASSERT( v != NULL );
 
-    apic_id = v->vcpu_id;
-
     vlapic->domain = v->domain;
 
-    vlapic->id = apic_id;
-
     vlapic->vcpu_id = v->vcpu_id;
 
-    vlapic->version = VLAPIC_VERSION;
-
-    vlapic->apic_base_msr = VLAPIC_BASE_MSR_INIT_VALUE;
-
-    if ( apic_id == 0 )
+    vlapic_set_reg(vlapic, APIC_ID, v->vcpu_id << 24);
+
+    vlapic_set_reg(vlapic, APIC_LVR, VLAPIC_VERSION);
+
+    for ( i = 0; i < VLAPIC_LVT_NUM; i++ )
+        vlapic_set_reg(vlapic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED);
+
+    vlapic_set_reg(vlapic, APIC_DFR, 0xffffffffU);
+
+    vlapic_set_reg(vlapic, APIC_SPIV, 0xff);
+
+    vlapic->apic_base_msr = MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
+
+    if ( v->vcpu_id == 0 )
         vlapic->apic_base_msr |= MSR_IA32_APICBASE_BSP;
 
-    vlapic->base_address = vlapic_get_base_address(vlapic);
-
-    for ( i = 0; i < VLAPIC_LVT_NUM; i++ )
-        vlapic->lvt[i] = VLAPIC_LVT_BIT_MASK;
-
-    vlapic->dest_format = 0xffffffffU;
-
-    vlapic->spurious_vec = 0xff;
+    vlapic->base_address = vlapic->apic_base_msr &
+                           MSR_IA32_APICBASE_BASE;
 
     hvm_vioapic_add_lapic(vlapic, v);
 
@@ -1048,8 +994,8 @@ static int vlapic_reset(struct vlapic *v
      */
     if ( !v->vcpu_id )
     {
-        vlapic->lvt[VLAPIC_LVT_LINT0] = 0x700;
-        vlapic->lvt[VLAPIC_LVT_LINT1] = 0x500;
+        vlapic_set_reg(vlapic, APIC_LVT0, APIC_MODE_EXTINT << 8);
+        vlapic_set_reg(vlapic, APIC_LVT1, APIC_MODE_NMI << 8);
         set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
     }
 #endif
@@ -1057,7 +1003,8 @@ static int vlapic_reset(struct vlapic *v
     HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
                 "vcpu=%p, id=%d, vlapic_apic_base_msr=0x%016"PRIx64", "
                 "base_address=0x%0lx.",
-                v, vlapic->id, vlapic->apic_base_msr, vlapic->base_address);
+                v,  GET_APIC_ID(vlapic_get_reg(vlapic, APIC_ID)),
+                vlapic->apic_base_msr, vlapic->base_address);
 
     return 1;
 }
@@ -1079,6 +1026,18 @@ int vlapic_init(struct vcpu *v)
 
     memset(vlapic, 0, sizeof(struct vlapic));
 
+    vlapic->regs_page = alloc_domheap_page(NULL);
+    if ( vlapic->regs_page == NULL )
+    {
+        printk("malloc vlapic regs error for vcpu %x\n", v->vcpu_id);
+        xfree(vlapic);
+        return -ENOMEM;
+    }
+
+    vlapic->regs = map_domain_page_global(page_to_mfn(vlapic->regs_page));
+
+    memset(vlapic->regs, 0, PAGE_SIZE);
+
     VLAPIC(v) = vlapic;
 
     vlapic->vcpu = v;
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/arch/x86/hvm/vmx/io.c
--- a/xen/arch/x86/hvm/vmx/io.c Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/io.c Wed Aug 02 10:07:03 2006 +0100
@@ -81,7 +81,7 @@ interrupt_post_injection(struct vcpu * v
 
     switch(type)
     {
-    case VLAPIC_DELIV_MODE_EXT:
+    case APIC_DM_EXTINT:
         break;
 
     default:
@@ -198,16 +198,17 @@ asmlinkage void vmx_intr_assist(void)
 
     highest_vector = cpu_get_interrupt(v, &intr_type); 
     switch (intr_type) {
-    case VLAPIC_DELIV_MODE_EXT:
-    case VLAPIC_DELIV_MODE_FIXED:
-    case VLAPIC_DELIV_MODE_LPRI:
+    case APIC_DM_EXTINT:
+    case APIC_DM_FIXED:
+    case APIC_DM_LOWEST:
         vmx_inject_extint(v, highest_vector, VMX_DELIVER_NO_ERROR_CODE);
         TRACE_3D(TRC_VMX_INT, v->domain->domain_id, highest_vector, 0);
         break;
-    case VLAPIC_DELIV_MODE_SMI:
-    case VLAPIC_DELIV_MODE_NMI:
-    case VLAPIC_DELIV_MODE_INIT:
-    case VLAPIC_DELIV_MODE_STARTUP:
+
+    case APIC_DM_SMI:
+    case APIC_DM_NMI:
+    case APIC_DM_INIT:
+    case APIC_DM_STARTUP:
     default:
         printk("Unsupported interrupt type\n");
         BUG();
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Wed Aug 02 10:07:03 2006 +0100
@@ -137,6 +137,8 @@ static void vmx_relinquish_guest_resourc
         if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) )
         {
             kill_timer(&VLAPIC(v)->vlapic_timer);
+            unmap_domain_page_global(VLAPIC(v)->regs);
+            free_domheap_page(VLAPIC(v)->regs_page);
             xfree(VLAPIC(v));
         }
     }
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/include/asm-ia64/vmx_platform.h
--- a/xen/include/asm-ia64/vmx_platform.h       Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/include/asm-ia64/vmx_platform.h       Wed Aug 02 10:07:03 2006 +0100
@@ -59,6 +59,17 @@ static inline int vlapic_set_irq(struct 
     return vmx_vcpu_pend_interrupt(t->vcpu, vec);
 }
 
+enum ioapic_irq_destination_types {
+       dest_Fixed = 0,
+       dest_LowestPrio = 1,
+       dest_SMI = 2,
+       dest__reserved_1 = 3,
+       dest_NMI = 4,
+       dest_INIT = 5,
+       dest__reserved_2 = 6,
+       dest_ExtINT = 7
+};
+
 /* As long as we register vlsapic to ioapic controller, it's said enabled */
 #define vlapic_enabled(l) 1
 #define hvm_apic_support(d) 1
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/include/asm-x86/hvm/support.h
--- a/xen/include/asm-x86/hvm/support.h Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/include/asm-x86/hvm/support.h Wed Aug 02 10:07:03 2006 +0100
@@ -29,7 +29,7 @@
 #ifndef NDEBUG
 #define HVM_DEBUG 1
 #else
-#define HVM_DEBUG 0
+#define HVM_DEBUG 1
 #endif
 
 #define        hvm_guest(v)    ((v)->arch.guest_context.flags & VGCF_HVM_GUEST)
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/include/asm-x86/hvm/vlapic.h
--- a/xen/include/asm-x86/hvm/vlapic.h  Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/include/asm-x86/hvm/vlapic.h  Wed Aug 02 10:07:03 2006 +0100
@@ -33,58 +33,31 @@ static __inline__ int find_highest_bit(u
 
 #define VLAPIC(v)                       (v->arch.hvm_vcpu.vlapic)
 
-#define VAPIC_ID_MASK                   0xff
-#define VAPIC_LDR_MASK                  (VAPIC_ID_MASK << 24)
 #define VLAPIC_VERSION                  0x00050014
 
-#define VLAPIC_BASE_MSR_MASK            0x00000000fffff900ULL
-#define VLAPIC_BASE_MSR_INIT_BASE_ADDR  0xfee00000U
-#define VLAPIC_BASE_MSR_BASE_ADDR_MASK  0xfffff000U
-#define VLAPIC_BASE_MSR_INIT_VALUE      (VLAPIC_BASE_MSR_INIT_BASE_ADDR | \
-                                         MSR_IA32_APICBASE_ENABLE)
 #define VLOCAL_APIC_MEM_LENGTH          (1 << 12)
 
-#define VLAPIC_LVT_TIMER                0
-#define VLAPIC_LVT_THERMAL              1
-#define VLAPIC_LVT_PERFORM              2
-#define VLAPIC_LVT_LINT0                3
-#define VLAPIC_LVT_LINT1                4
-#define VLAPIC_LVT_ERROR                5
 #define VLAPIC_LVT_NUM                  6
 
-#define VLAPIC_LVT_BIT_MASK             (1 << 16)
-#define VLAPIC_LVT_BIT_VECTOR           0xff
-#define VLAPIC_LVT_BIT_DELIMOD          (0x7 << 8)
-#define VLAPIC_LVT_BIT_DELISTATUS       (1 << 12)
-#define VLAPIC_LVT_BIT_POLARITY         (1 << 13)
-#define VLAPIC_LVT_BIT_IRR              (1 << 14)
-#define VLAPIC_LVT_BIT_TRIG             (1 << 15)
-#define VLAPIC_LVT_TIMERMODE            (1 << 17)
+#define VLAPIC_ID(vlapic)   \
+    (GET_APIC_ID(vlapic_get_reg(vlapic, APIC_ID)))
 
-#define VLAPIC_DELIV_MODE_FIXED         0x0
-#define VLAPIC_DELIV_MODE_LPRI          0x1
-#define VLAPIC_DELIV_MODE_SMI           0x2
-#define VLAPIC_DELIV_MODE_RESERVED      0x3
-#define VLAPIC_DELIV_MODE_NMI           0x4
-#define VLAPIC_DELIV_MODE_INIT          0x5
-#define VLAPIC_DELIV_MODE_STARTUP       0x6
-#define VLAPIC_DELIV_MODE_EXT           0x7
+/* followed define is not in apicdef.h */
+#define APIC_SHORT_MASK                  0xc0000
+#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_NO_SHORTHAND             0x0
-#define VLAPIC_SHORTHAND_SELF           0x1
-#define VLAPIC_SHORTHAND_INCLUDE_SELF   0x2
-#define VLAPIC_SHORTHAND_EXCLUDE_SELF   0x3
+#define vlapic_lvt_vector(vlapic, lvt_type)     \
+    (vlapic_get_reg(vlapic, lvt_type) & APIC_VECTOR_MASK)
 
-#define vlapic_lvt_timer_enabled(vlapic)    \
-    (!((vlapic)->lvt[VLAPIC_LVT_TIMER] & VLAPIC_LVT_BIT_MASK))
+#define vlapic_lvt_dm(vlapic, lvt_type)           \
+    (vlapic_get_reg(vlapic, lvt_type) & APIC_MODE_MASK)
 
-#define vlapic_lvt_vector(vlapic, type)     \
-    ((vlapic)->lvt[(type)] & VLAPIC_LVT_BIT_VECTOR)
-
-#define vlapic_lvt_dm(value)            (((value) >> 8) && 7)
-#define vlapic_lvt_timer_period(vlapic)     \
-    ((vlapic)->lvt[VLAPIC_LVT_TIMER] & VLAPIC_LVT_TIMERMODE)
+#define vlapic_lvtt_period(vlapic)     \
+    (vlapic_get_reg(vlapic, APIC_LVTT) & APIC_LVT_TIMER_PERIODIC)
 
 #define _VLAPIC_GLOB_DISABLE            0x0
 #define VLAPIC_GLOB_DISABLE_MASK        0x1
@@ -98,8 +71,12 @@ static __inline__ int find_highest_bit(u
 #define vlapic_global_enabled(vlapic)       \
     (!(test_bit(_VLAPIC_GLOB_DISABLE, &(vlapic)->status)))
 
-#define VLAPIC_IRR(t)   ((t)->irr[0])
-#define VLAPIC_ID(t)    ((t)->id)
+#define LVT_MASK \
+    APIC_LVT_MASKED | APIC_SEND_PENDING | APIC_VECTOR_MASK
+
+#define LINT_MASK   \
+    LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY |\
+    APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER
 
 typedef struct direct_intr_info {
     int deliver_mode;
@@ -109,72 +86,52 @@ typedef struct direct_intr_info {
 #define MAX_VECTOR      256
 
 struct vlapic {
-    uint32_t           version;
     uint32_t           status;
-    uint32_t           id;
     uint32_t           vcpu_id;
+    uint64_t           apic_base_msr;
     unsigned long      base_address;
-    unsigned long      isr[BITS_TO_LONGS(MAX_VECTOR)];
-    unsigned long      irr[BITS_TO_LONGS(MAX_VECTOR)];
-    unsigned long      tmr[BITS_TO_LONGS(MAX_VECTOR)];
-    uint32_t           task_priority;
-    uint32_t           processor_priority;
-    uint32_t           logical_dest;
-    uint32_t           dest_format;
-    uint32_t           spurious_vec;
-    uint32_t           lvt[6];
-    uint32_t           timer_initial_count;
-    uint32_t           timer_current_count;
-    uint32_t           timer_divconf;
     uint32_t           timer_divide_count;
     struct timer       vlapic_timer;
     int                intr_pending_count[MAX_VECTOR];
-    s_time_t           timer_current_update;
-    uint32_t           icr_high;
-    uint32_t           icr_low;
+    s_time_t           timer_last_update;
     direct_intr_info_t direct_intr;
     uint32_t           err_status;
-    unsigned long      init_ticks;
     uint32_t           err_write_count;
-    uint64_t           apic_base_msr;
     struct vcpu        *vcpu;
     struct domain      *domain;
+    struct page_info   *regs_page;
+    void               *regs;
 };
 
-static inline int vlapic_set_irq(struct vlapic *t, uint8_t vec, uint8_t trig)
+static inline int vlapic_set_irq(struct vlapic *vlapic,
+                                 uint8_t vec, uint8_t trig)
 {
     int ret;
 
-    ret = test_and_set_bit(vec, &t->irr[0]);
+    ret = test_and_set_bit(vec, vlapic->regs + APIC_IRR);
     if ( trig )
-       set_bit(vec, &t->tmr[0]);
+        set_bit(vec, vlapic->regs + APIC_TMR);
 
     /* We may need to wake up target vcpu, besides set pending bit here */
     return ret;
 }
 
-static inline int vlapic_timer_active(struct vlapic *vlapic)
+static inline uint32_t vlapic_get_reg(struct vlapic *vlapic, uint32_t reg)
 {
-    return active_timer(&vlapic->vlapic_timer);
+    return  *( (uint32_t *)(vlapic->regs + reg));
 }
 
-int vlapic_find_highest_irr(struct vlapic *vlapic);
+static inline void vlapic_set_reg(struct vlapic *vlapic,
+  uint32_t reg, uint32_t val)
+{
+    *((uint32_t *)(vlapic->regs + reg)) = val;
+}
 
-int vlapic_find_highest_isr(struct vlapic *vlapic);
-
-static uint32_t inline vlapic_get_base_address(struct vlapic *vlapic)
-{
-    return (vlapic->apic_base_msr & VLAPIC_BASE_MSR_BASE_ADDR_MASK);
-}
 
 void vlapic_post_injection(struct vcpu* v, int vector, int deliver_mode);
 
 int cpu_has_apic_interrupt(struct vcpu* v);
 int cpu_get_apic_interrupt(struct vcpu* v, int *mode);
-
-extern uint32_t vlapic_update_ppr(struct vlapic *vlapic);
-
-int vlapic_update(struct vcpu *v);
 
 extern int vlapic_init(struct vcpu *vc);
 
diff -r 637b6d60e792 -r a6cb8ba24a91 xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Wed Aug 02 10:04:27 2006 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Wed Aug 02 10:07:03 2006 +0100
@@ -153,7 +153,7 @@ extern unsigned int cpu_rev;
 /*
  * Exit Qualifications for MOV for Control Register Access
  */
-#define CONTROL_REG_ACCESS_NUM          0x7     /* 2:0, number of control 
register */
+#define CONTROL_REG_ACCESS_NUM          0xf     /* 3:0, number of control 
register */
 #define CONTROL_REG_ACCESS_TYPE         0x30    /* 5:4, access type */
 #define CONTROL_REG_ACCESS_REG          0xf00   /* 10:8, general purpose 
register */
 #define LMSW_SOURCE_DATA  (0xFFFF << 16) /* 16:31 lmsw source */

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