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] Place all APIC registers into one p

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [HVM] Place all APIC registers into one page in native format.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 02 Aug 2006 10:40:20 +0000
Delivery-date: Wed, 02 Aug 2006 03:43:36 -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 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [HVM] Place all APIC registers into one page in native format., Xen patchbot-unstable <=