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

[Xen-changelog] [xen-unstable] [HVM] Save/restore cleanups 03: IRQ



# HG changeset patch
# User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
# Date 1169291860 0
# Node ID 2457741f4ec308b1dd3368296df88a3806249afe
# Parent  dccdc3ee0efca7894870e1699233eca1d9bfc463
[HVM] Save/restore cleanups 03: IRQ
IRQ, PIC, IOAPIC and LAPIC
Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/hpet.c           |    5 -
 xen/arch/x86/hvm/hvm.c            |    2 
 xen/arch/x86/hvm/irq.c            |   52 +++++------
 xen/arch/x86/hvm/svm/svm.c        |    2 
 xen/arch/x86/hvm/vioapic.c        |  119 ++++++++-----------------
 xen/arch/x86/hvm/vlapic.c         |   99 +++++++++------------
 xen/arch/x86/hvm/vmx/vmx.c        |    2 
 xen/arch/x86/hvm/vpic.c           |   84 +++++------------
 xen/include/asm-x86/hvm/domain.h  |    7 +
 xen/include/asm-x86/hvm/irq.h     |   65 -------------
 xen/include/asm-x86/hvm/vioapic.h |   41 --------
 xen/include/asm-x86/hvm/vlapic.h  |   25 ++---
 xen/include/asm-x86/hvm/vpic.h    |   46 ---------
 xen/include/public/hvm/save.h     |  178 +++++++++++++++++++++++++++++++++++++-
 14 files changed, 334 insertions(+), 393 deletions(-)

diff -r dccdc3ee0efc -r 2457741f4ec3 xen/arch/x86/hvm/hpet.c
--- a/xen/arch/x86/hvm/hpet.c   Sat Jan 20 11:17:39 2007 +0000
+++ b/xen/arch/x86/hvm/hpet.c   Sat Jan 20 11:17:40 2007 +0000
@@ -314,7 +314,6 @@ static void hpet_route_interrupt(HPETSta
 {
     unsigned int tn_int_route = timer_int_route(h, tn);
     struct domain *d = h->vcpu->domain;
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
 
     if ( (tn <= 1) && (h->hpet.config & HPET_CFG_LEGACY) )
     {
@@ -336,9 +335,9 @@ static void hpet_route_interrupt(HPETSta
     }
 
     /* We only support edge-triggered interrupt now  */
-    spin_lock(&hvm_irq->lock);
+    spin_lock(&d->arch.hvm_domain.irq_lock);
     vioapic_irq_positive_edge(d, tn_int_route);
-    spin_unlock(&hvm_irq->lock);
+    spin_unlock(&d->arch.hvm_domain.irq_lock);
 }
 
 static void hpet_timer_fn(void *opaque)
diff -r dccdc3ee0efc -r 2457741f4ec3 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Sat Jan 20 11:17:39 2007 +0000
+++ b/xen/arch/x86/hvm/hvm.c    Sat Jan 20 11:17:40 2007 +0000
@@ -135,7 +135,7 @@ int hvm_domain_initialise(struct domain 
 
     spin_lock_init(&d->arch.hvm_domain.pbuf_lock);
     spin_lock_init(&d->arch.hvm_domain.buffered_io_lock);
-    spin_lock_init(&d->arch.hvm_domain.irq.lock);
+    spin_lock_init(&d->arch.hvm_domain.irq_lock);
 
     rc = shadow_enable(d, SHM2_refcounts|SHM2_translate|SHM2_external);
     if ( rc != 0 )
diff -r dccdc3ee0efc -r 2457741f4ec3 xen/arch/x86/hvm/irq.c
--- a/xen/arch/x86/hvm/irq.c    Sat Jan 20 11:17:39 2007 +0000
+++ b/xen/arch/x86/hvm/irq.c    Sat Jan 20 11:17:40 2007 +0000
@@ -28,7 +28,7 @@ static void __hvm_pci_intx_assert(
 static void __hvm_pci_intx_assert(
     struct domain *d, unsigned int device, unsigned int intx)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq;
     unsigned int gsi, link, isa_irq;
 
     ASSERT((device <= 31) && (intx <= 3));
@@ -53,17 +53,15 @@ void hvm_pci_intx_assert(
 void hvm_pci_intx_assert(
     struct domain *d, unsigned int device, unsigned int intx)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
-
-    spin_lock(&hvm_irq->lock);
+    spin_lock(&d->arch.hvm_domain.irq_lock);
     __hvm_pci_intx_assert(d, device, intx);
-    spin_unlock(&hvm_irq->lock);
+    spin_unlock(&d->arch.hvm_domain.irq_lock);
 }
 
 static void __hvm_pci_intx_deassert(
     struct domain *d, unsigned int device, unsigned int intx)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq;
     unsigned int gsi, link, isa_irq;
 
     ASSERT((device <= 31) && (intx <= 3));
@@ -84,22 +82,20 @@ void hvm_pci_intx_deassert(
 void hvm_pci_intx_deassert(
     struct domain *d, unsigned int device, unsigned int intx)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
-
-    spin_lock(&hvm_irq->lock);
+    spin_lock(&d->arch.hvm_domain.irq_lock);
     __hvm_pci_intx_deassert(d, device, intx);
-    spin_unlock(&hvm_irq->lock);
+    spin_unlock(&d->arch.hvm_domain.irq_lock);
 }
 
 void hvm_isa_irq_assert(
     struct domain *d, unsigned int isa_irq)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq;
     unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
 
     ASSERT(isa_irq <= 15);
 
-    spin_lock(&hvm_irq->lock);
+    spin_lock(&d->arch.hvm_domain.irq_lock);
 
     if ( !__test_and_set_bit(isa_irq, &hvm_irq->isa_irq) &&
          (hvm_irq->gsi_assert_count[gsi]++ == 0) )
@@ -108,31 +104,31 @@ void hvm_isa_irq_assert(
         vpic_irq_positive_edge(d, isa_irq);
     }
 
-    spin_unlock(&hvm_irq->lock);
+    spin_unlock(&d->arch.hvm_domain.irq_lock);
 }
 
 void hvm_isa_irq_deassert(
     struct domain *d, unsigned int isa_irq)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq;
     unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
 
     ASSERT(isa_irq <= 15);
 
-    spin_lock(&hvm_irq->lock);
+    spin_lock(&d->arch.hvm_domain.irq_lock);
 
     if ( __test_and_clear_bit(isa_irq, &hvm_irq->isa_irq) &&
          (--hvm_irq->gsi_assert_count[gsi] == 0) )
         vpic_irq_negative_edge(d, isa_irq);
 
-    spin_unlock(&hvm_irq->lock);
+    spin_unlock(&d->arch.hvm_domain.irq_lock);
 }
 
 void hvm_set_callback_irq_level(void)
 {
     struct vcpu *v = current;
     struct domain *d = v->domain;
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq;
     unsigned int gsi, pdev, pintx, asserted;
 
     /* Fast lock-free tests. */
@@ -140,7 +136,7 @@ void hvm_set_callback_irq_level(void)
          (hvm_irq->callback_via_type == HVMIRQ_callback_none) )
         return;
 
-    spin_lock(&hvm_irq->lock);
+    spin_lock(&d->arch.hvm_domain.irq_lock);
 
     /* NB. Do not check the evtchn_upcall_mask. It is not used in HVM mode. */
     asserted = !!vcpu_info(v, evtchn_upcall_pending);
@@ -177,17 +173,17 @@ void hvm_set_callback_irq_level(void)
     }
 
  out:
-    spin_unlock(&hvm_irq->lock);
+    spin_unlock(&d->arch.hvm_domain.irq_lock);
 }
 
 void hvm_set_pci_link_route(struct domain *d, u8 link, u8 isa_irq)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq;
     u8 old_isa_irq;
 
     ASSERT((link <= 3) && (isa_irq <= 15));
 
-    spin_lock(&hvm_irq->lock);
+    spin_lock(&d->arch.hvm_domain.irq_lock);
 
     old_isa_irq = hvm_irq->pci_link_route[link];
     if ( old_isa_irq == isa_irq )
@@ -207,7 +203,7 @@ void hvm_set_pci_link_route(struct domai
     }
 
  out:
-    spin_unlock(&hvm_irq->lock);
+    spin_unlock(&d->arch.hvm_domain.irq_lock);
 
     dprintk(XENLOG_G_INFO, "Dom%u PCI link %u changed %u -> %u\n",
             d->domain_id, link, old_isa_irq, isa_irq);
@@ -215,7 +211,7 @@ void hvm_set_pci_link_route(struct domai
 
 void hvm_set_callback_via(struct domain *d, uint64_t via)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq;
     unsigned int gsi=0, pdev=0, pintx=0;
     uint8_t via_type;
 
@@ -224,7 +220,7 @@ void hvm_set_callback_via(struct domain 
          (via_type > HVMIRQ_callback_pci_intx) )
         via_type = HVMIRQ_callback_none;
 
-    spin_lock(&hvm_irq->lock);
+    spin_lock(&d->arch.hvm_domain.irq_lock);
 
     /* Tear down old callback via. */
     if ( hvm_irq->callback_via_asserted )
@@ -271,7 +267,7 @@ void hvm_set_callback_via(struct domain 
         break;
     }
 
-    spin_unlock(&hvm_irq->lock);
+    spin_unlock(&d->arch.hvm_domain.irq_lock);
 
     dprintk(XENLOG_G_INFO, "Dom%u callback via changed to ", d->domain_id);
     switch ( via_type )
@@ -300,7 +296,7 @@ int cpu_has_pending_irq(struct vcpu *v)
     if ( !vlapic_accept_pic_intr(v) )
         return 0;
 
-    return plat->irq.vpic[0].int_output;
+    return plat->vpic[0].int_output;
 }
 
 int cpu_get_interrupt(struct vcpu *v, int *type)
@@ -322,7 +318,7 @@ int get_isa_irq_vector(struct vcpu *v, i
     unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
 
     if ( type == APIC_DM_EXTINT )
-        return (v->domain->arch.hvm_domain.irq.vpic[isa_irq >> 3].irq_base
+        return (v->domain->arch.hvm_domain.vpic[isa_irq >> 3].irq_base
                 + (isa_irq & 7));
 
     return domain_vioapic(v->domain)->redirtbl[gsi].fields.vector;
@@ -335,7 +331,7 @@ int is_isa_irq_masked(struct vcpu *v, in
     if ( is_lvtt(v, isa_irq) )
         return !is_lvtt_enabled(v);
 
-    return ((v->domain->arch.hvm_domain.irq.vpic[isa_irq >> 3].imr &
+    return ((v->domain->arch.hvm_domain.vpic[isa_irq >> 3].imr &
              (1 << (isa_irq & 7))) &&
             domain_vioapic(v->domain)->redirtbl[gsi].fields.mask);
 }
diff -r dccdc3ee0efc -r 2457741f4ec3 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Sat Jan 20 11:17:39 2007 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c        Sat Jan 20 11:17:40 2007 +0000
@@ -1960,7 +1960,7 @@ static inline void svm_do_msr_access(
             msr_content = vmcb->sysenter_eip;
             break;
         case MSR_IA32_APICBASE:
-            msr_content = vcpu_vlapic(v)->apic_base_msr;
+            msr_content = vcpu_vlapic(v)->hw.apic_base_msr;
             break;
         default:
             if (long_mode_do_msr_read(regs))
diff -r dccdc3ee0efc -r 2457741f4ec3 xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c        Sat Jan 20 11:17:39 2007 +0000
+++ b/xen/arch/x86/hvm/vioapic.c        Sat Jan 20 11:17:40 2007 +0000
@@ -47,9 +47,9 @@
 #define opt_hvm_debug_level opt_vmx_debug_level
 #endif
 
-static void vioapic_deliver(struct vioapic *vioapic, int irq);
-
-static unsigned long vioapic_read_indirect(struct vioapic *vioapic,
+static void vioapic_deliver(struct hvm_hw_vioapic *vioapic, int irq);
+
+static unsigned long vioapic_read_indirect(struct hvm_hw_vioapic *vioapic,
                                            unsigned long addr,
                                            unsigned long length)
 {
@@ -96,7 +96,7 @@ static unsigned long vioapic_read(struct
                                   unsigned long addr,
                                   unsigned long length)
 {
-    struct vioapic *vioapic = domain_vioapic(v->domain);
+    struct hvm_hw_vioapic *vioapic = domain_vioapic(v->domain);
     uint32_t result;
 
     HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "vioapic_read addr %lx\n", addr);
@@ -122,13 +122,13 @@ static unsigned long vioapic_read(struct
 }
 
 static void vioapic_write_redirent(
-    struct vioapic *vioapic, unsigned int idx, int top_word, uint32_t val)
+    struct hvm_hw_vioapic *vioapic, unsigned int idx, int top_word, uint32_t 
val)
 {
     struct domain *d = vioapic_domain(vioapic);
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq;
     union vioapic_redir_entry *pent, ent;
 
-    spin_lock(&hvm_irq->lock);
+    spin_lock(&d->arch.hvm_domain.irq_lock);
 
     pent = &vioapic->redirtbl[idx];
     ent  = *pent;
@@ -157,11 +157,11 @@ static void vioapic_write_redirent(
         vioapic_deliver(vioapic, idx);
     }
 
-    spin_unlock(&hvm_irq->lock);
+    spin_unlock(&d->arch.hvm_domain.irq_lock);
 }
 
 static void vioapic_write_indirect(
-    struct vioapic *vioapic, unsigned long addr,
+    struct hvm_hw_vioapic *vioapic, unsigned long addr,
     unsigned long length, unsigned long val)
 {
     switch ( vioapic->ioregsel )
@@ -206,7 +206,7 @@ static void vioapic_write(struct vcpu *v
                           unsigned long length,
                           unsigned long val)
 {
-    struct vioapic *vioapic = domain_vioapic(v->domain);
+    struct hvm_hw_vioapic *vioapic = domain_vioapic(v->domain);
 
     addr &= 0xff;
 
@@ -233,7 +233,7 @@ static void vioapic_write(struct vcpu *v
 
 static int vioapic_range(struct vcpu *v, unsigned long addr)
 {
-    struct vioapic *vioapic = domain_vioapic(v->domain);
+    struct hvm_hw_vioapic *vioapic = domain_vioapic(v->domain);
 
     return ((addr >= vioapic->base_address &&
              (addr < vioapic->base_address + VIOAPIC_MEM_LENGTH)));
@@ -246,7 +246,7 @@ struct hvm_mmio_handler vioapic_mmio_han
 };
 
 static void ioapic_inj_irq(
-    struct vioapic *vioapic,
+    struct hvm_hw_vioapic *vioapic,
     struct vlapic *target,
     uint8_t vector,
     uint8_t trig_mode,
@@ -270,7 +270,7 @@ static void ioapic_inj_irq(
 }
 
 static uint32_t ioapic_get_delivery_bitmask(
-    struct vioapic *vioapic, uint16_t dest, uint8_t dest_mode)
+    struct hvm_hw_vioapic *vioapic, uint16_t dest, uint8_t dest_mode)
 {
     uint32_t mask = 0;
     struct vcpu *v;
@@ -316,7 +316,7 @@ static inline int pit_channel0_enabled(v
     return pt->enabled;
 }
 
-static void vioapic_deliver(struct vioapic *vioapic, int irq)
+static void vioapic_deliver(struct hvm_hw_vioapic *vioapic, int irq)
 {
     uint16_t dest = vioapic->redirtbl[irq].fields.dest_id;
     uint8_t dest_mode = vioapic->redirtbl[irq].fields.dest_mode;
@@ -327,7 +327,7 @@ static void vioapic_deliver(struct vioap
     struct vlapic *target;
     struct vcpu *v;
 
-    ASSERT(spin_is_locked(&vioapic_domain(vioapic)->arch.hvm_domain.irq.lock));
+    ASSERT(spin_is_locked(&vioapic_domain(vioapic)->arch.hvm_domain.irq_lock));
 
     HVM_DBG_LOG(DBG_LEVEL_IOAPIC,
                 "dest=%x dest_mode=%x delivery_mode=%x "
@@ -409,13 +409,13 @@ static void vioapic_deliver(struct vioap
 
 void vioapic_irq_positive_edge(struct domain *d, unsigned int irq)
 {
-    struct vioapic *vioapic = domain_vioapic(d);
+    struct hvm_hw_vioapic *vioapic = domain_vioapic(d);
     union vioapic_redir_entry *ent;
 
     HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_irq_positive_edge irq %x", irq);
 
     ASSERT(irq < VIOAPIC_NUM_PINS);
-    ASSERT(spin_is_locked(&d->arch.hvm_domain.irq.lock));
+    ASSERT(spin_is_locked(&d->arch.hvm_domain.irq_lock));
 
     ent = &vioapic->redirtbl[irq];
     if ( ent->fields.mask )
@@ -432,7 +432,7 @@ void vioapic_irq_positive_edge(struct do
     }
 }
 
-static int get_eoi_gsi(struct vioapic *vioapic, int vector)
+static int get_eoi_gsi(struct hvm_hw_vioapic *vioapic, int vector)
 {
     int i;
 
@@ -445,12 +445,12 @@ static int get_eoi_gsi(struct vioapic *v
 
 void vioapic_update_EOI(struct domain *d, int vector)
 {
-    struct vioapic *vioapic = domain_vioapic(d);
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_hw_vioapic *vioapic = domain_vioapic(d);
+    struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq;
     union vioapic_redir_entry *ent;
     int gsi;
 
-    spin_lock(&hvm_irq->lock);
+    spin_lock(&d->arch.hvm_domain.irq_lock);
 
     if ( (gsi = get_eoi_gsi(vioapic, vector)) == -1 )
     {
@@ -470,11 +470,11 @@ void vioapic_update_EOI(struct domain *d
     }
 
  out:
-    spin_unlock(&hvm_irq->lock);
+    spin_unlock(&d->arch.hvm_domain.irq_lock);
 }
 
 #ifdef HVM_DEBUG_SUSPEND
-static void ioapic_info(struct vioapic *s)
+static void ioapic_info(struct hvm_hw_vioapic *s)
 {
     int i;
     printk("*****ioapic state:*****\n");
@@ -486,7 +486,7 @@ static void ioapic_info(struct vioapic *
     }
 
 }
-static void hvmirq_info(struct hvm_irq *hvm_irq)
+static void hvmirq_info(struct hvm_hw_irq *hvm_irq)
 {
     int i;
     printk("*****hvmirq state:*****\n");
@@ -515,87 +515,44 @@ static void hvmirq_info(struct hvm_irq *
     printk("hvmirq round_robin_prev_vcpu:0x%"PRIx8".\n", 
hvm_irq->round_robin_prev_vcpu);
 }
 #else
-static void ioapic_info(struct vioapic *s)
-{
-}
-static void hvmirq_info(struct hvm_irq *hvm_irq)
+static void ioapic_info(struct hvm_hw_vioapic *s)
+{
+}
+static void hvmirq_info(struct hvm_hw_irq *hvm_irq)
 {
 }
 #endif
 
 static void ioapic_save(hvm_domain_context_t *h, void *opaque)
 {
-    int i;
     struct domain *d = opaque;
-    struct vioapic *s = domain_vioapic(d);
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_hw_vioapic *s = domain_vioapic(d);
+    struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq;
 
     ioapic_info(s);
     hvmirq_info(hvm_irq);
 
-    /* save iopaic state*/
-    hvm_put_32u(h, s->ioregsel);
-    hvm_put_32u(h, s->id);
-    hvm_put_64u(h, s->base_address);
-    for (i = 0; i < VIOAPIC_NUM_PINS; i++) {
-        hvm_put_64u(h, s->redirtbl[i].bits);
-    }
+    /* save io-apic state*/
+    hvm_put_struct(h, s);
 
     /* save hvm irq state */
-    hvm_put_buffer(h, (char*)hvm_irq->pci_intx, 16);
-    hvm_put_buffer(h, (char*)hvm_irq->isa_irq, 2);
-    hvm_put_32u(h, hvm_irq->callback_via_asserted);
-    hvm_put_32u(h, hvm_irq->callback_via_type);
-    hvm_put_32u(h, hvm_irq->callback_via.gsi);
-
-    for (i = 0; i < 4; i++)
-        hvm_put_8u(h, hvm_irq->pci_link_route[i]);
-
-    for (i = 0; i < 4; i++)
-        hvm_put_8u(h, hvm_irq->pci_link_assert_count[i]);
-
-    for (i = 0; i < VIOAPIC_NUM_PINS; i++)
-        hvm_put_8u(h, hvm_irq->gsi_assert_count[i]);
-
-    hvm_put_8u(h, hvm_irq->round_robin_prev_vcpu);
-
+    hvm_put_struct(h, hvm_irq);
 }
 
 static int ioapic_load(hvm_domain_context_t *h, void *opaque, int version_id)
 {
-    int i;
     struct domain *d = opaque;
-    struct vioapic *s = domain_vioapic(d);
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_hw_vioapic *s = domain_vioapic(d);
+    struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq;
     
     if (version_id != 1)
         return -EINVAL;
 
     /* restore ioapic state */
-    s->ioregsel = hvm_get_32u(h);
-    s->id = hvm_get_32u(h);
-    s->base_address = hvm_get_64u(h);
-    for (i = 0; i < VIOAPIC_NUM_PINS; i++) {
-        s->redirtbl[i].bits = hvm_get_64u(h);
-    }
+    hvm_get_struct(h, s);
 
     /* restore irq state */
-    hvm_get_buffer(h, (char*)hvm_irq->pci_intx, 16);
-    hvm_get_buffer(h, (char*)hvm_irq->isa_irq, 2);
-    hvm_irq->callback_via_asserted = hvm_get_32u(h);
-    hvm_irq->callback_via_type = hvm_get_32u(h);
-    hvm_irq->callback_via.gsi = hvm_get_32u(h);
-
-    for (i = 0; i < 4; i++)
-        hvm_irq->pci_link_route[i] = hvm_get_8u(h);
-
-    for (i = 0; i < 4; i++)
-        hvm_irq->pci_link_assert_count[i] = hvm_get_8u(h);
-
-    for (i = 0; i < VIOAPIC_NUM_PINS; i++)
-        hvm_irq->gsi_assert_count[i] = hvm_get_8u(h);
-
-    hvm_irq->round_robin_prev_vcpu = hvm_get_8u(h);
+    hvm_get_struct(h, hvm_irq);
 
     ioapic_info(s);
     hvmirq_info(hvm_irq);
@@ -605,7 +562,7 @@ static int ioapic_load(hvm_domain_contex
 
 void vioapic_init(struct domain *d)
 {
-    struct vioapic *vioapic = domain_vioapic(d);
+    struct hvm_hw_vioapic *vioapic = domain_vioapic(d);
     int i;
 
     hvm_register_savevm(d, "xen_hvm_ioapic", 0, 1, ioapic_save, ioapic_load, 
d);
diff -r dccdc3ee0efc -r 2457741f4ec3 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Sat Jan 20 11:17:39 2007 +0000
+++ b/xen/arch/x86/hvm/vlapic.c Sat Jan 20 11:17:40 2007 +0000
@@ -81,7 +81,7 @@ static unsigned int vlapic_lvt_mask[VLAP
     (vlapic_get_reg(vlapic, APIC_LVTT) & APIC_LVT_TIMER_PERIODIC)
 
 #define vlapic_base_address(vlapic)                             \
-    (vlapic->apic_base_msr & MSR_IA32_APICBASE_BASE)
+    (vlapic->hw.apic_base_msr & MSR_IA32_APICBASE_BASE)
 
 static int vlapic_reset(struct vlapic *vlapic);
 
@@ -100,15 +100,16 @@ static int vlapic_reset(struct vlapic *v
 #define vlapic_clear_vector(vec, bitmap)                        \
     clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec))
 
-static int vlapic_find_highest_vector(u32 *bitmap)
-{
+static int vlapic_find_highest_vector(void *bitmap)
+{
+    uint32_t *word = bitmap;
     int word_offset = MAX_VECTOR / 32;
 
     /* Work backwards through the bitmap (first 32-bit word in every four). */
-    while ( (word_offset != 0) && (bitmap[(--word_offset)*4] == 0) )
+    while ( (word_offset != 0) && (word[(--word_offset)*4] == 0) )
         continue;
 
-    return (fls(bitmap[word_offset*4]) - 1) + (word_offset * 32);
+    return (fls(word[word_offset*4]) - 1) + (word_offset * 32);
 }
 
 
@@ -118,19 +119,19 @@ static int vlapic_find_highest_vector(u3
 
 static int vlapic_test_and_set_irr(int vector, struct vlapic *vlapic)
 {
-    return vlapic_test_and_set_vector(vector, vlapic->regs + APIC_IRR);
+    return vlapic_test_and_set_vector(vector, &vlapic->regs->data[APIC_IRR]);
 }
 
 static void vlapic_clear_irr(int vector, struct vlapic *vlapic)
 {
-    vlapic_clear_vector(vector, vlapic->regs + APIC_IRR);
+    vlapic_clear_vector(vector, &vlapic->regs->data[APIC_IRR]);
 }
 
 int vlapic_find_highest_irr(struct vlapic *vlapic)
 {
     int result;
 
-    result = vlapic_find_highest_vector(vlapic->regs + APIC_IRR);
+    result = vlapic_find_highest_vector(&vlapic->regs->data[APIC_IRR]);
     ASSERT((result == -1) || (result >= 16));
 
     return result;
@@ -142,7 +143,7 @@ int vlapic_set_irq(struct vlapic *vlapic
 
     ret = !vlapic_test_and_set_irr(vec, vlapic);
     if ( trig )
-        vlapic_set_vector(vec, vlapic->regs + APIC_TMR);
+        vlapic_set_vector(vec, &vlapic->regs->data[APIC_TMR]);
 
     /* We may need to wake up target vcpu, besides set pending bit here */
     return ret;
@@ -152,7 +153,7 @@ int vlapic_find_highest_isr(struct vlapi
 {
     int result;
 
-    result = vlapic_find_highest_vector(vlapic->regs + APIC_ISR);
+    result = vlapic_find_highest_vector(&vlapic->regs->data[APIC_ISR]);
     ASSERT((result == -1) || (result >= 16));
 
     return result;
@@ -279,7 +280,7 @@ static int vlapic_accept_irq(struct vcpu
         {
             HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
                         "level trig mode for vector %d\n", vector);
-            vlapic_set_vector(vector, vlapic->regs + APIC_TMR);
+            vlapic_set_vector(vector, &vlapic->regs->data[APIC_TMR]);
         }
 
         vcpu_kick(v);
@@ -375,9 +376,9 @@ void vlapic_EOI_set(struct vlapic *vlapi
     if ( vector == -1 )
         return;
 
-    vlapic_clear_vector(vector, vlapic->regs + APIC_ISR);
-
-    if ( vlapic_test_and_clear_vector(vector, vlapic->regs + APIC_TMR) )
+    vlapic_clear_vector(vector, &vlapic->regs->data[APIC_ISR]);
+
+    if ( vlapic_test_and_clear_vector(vector, &vlapic->regs->data[APIC_TMR]) )
         vioapic_update_EOI(vlapic_domain(vlapic), vector);
 }
 
@@ -433,7 +434,7 @@ static uint32_t vlapic_get_tmcct(struct 
 
     counter_passed = (hvm_get_guest_time(v) - vlapic->pt.last_plt_gtime) // TSC
                      * 1000000000ULL / ticks_per_sec(v) // NS
-                     / APIC_BUS_CYCLE_NS / vlapic->timer_divisor;
+                     / APIC_BUS_CYCLE_NS / vlapic->hw.timer_divisor;
     tmcct = tmict - counter_passed;
 
     HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER,
@@ -450,12 +451,12 @@ static void vlapic_set_tdcr(struct vlapi
     val &= 0xb;
     vlapic_set_reg(vlapic, APIC_TDCR, val);
 
-    /* Update the demangled timer_divisor. */
+    /* Update the demangled hw.timer_divisor. */
     val = ((val & 3) | ((val & 8) >> 1)) + 1;
-    vlapic->timer_divisor = 1 << (val & 7);
+    vlapic->hw.timer_divisor = 1 << (val & 7);
 
     HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER,
-                "vlapic_set_tdcr timer_divisor: %d.", vlapic->timer_divisor);
+                "vlapic_set_tdcr timer_divisor: %d.", 
vlapic->hw.timer_divisor);
 }
 
 static void vlapic_read_aligned(struct vlapic *vlapic, unsigned int offset,
@@ -614,7 +615,7 @@ static void vlapic_write(struct vcpu *v,
             int i;
             uint32_t lvt_val;
 
-            vlapic->disabled |= VLAPIC_SW_DISABLED;
+            vlapic->hw.disabled |= VLAPIC_SW_DISABLED;
 
             for ( i = 0; i < VLAPIC_LVT_NUM; i++ )
             {
@@ -624,7 +625,7 @@ static void vlapic_write(struct vcpu *v,
             }
         }
         else
-            vlapic->disabled &= ~VLAPIC_SW_DISABLED;
+            vlapic->hw.disabled &= ~VLAPIC_SW_DISABLED;
         break;
 
     case APIC_ESR:
@@ -656,7 +657,7 @@ static void vlapic_write(struct vcpu *v,
 
     case APIC_TMICT:
     {
-        uint64_t period = APIC_BUS_CYCLE_NS * (uint32_t)val * 
vlapic->timer_divisor;
+        uint64_t period = APIC_BUS_CYCLE_NS * (uint32_t)val * 
vlapic->hw.timer_divisor;
 
         vlapic_set_reg(vlapic, APIC_TMICT, val);
         create_periodic_time(current, &vlapic->pt, period, vlapic->pt.irq,
@@ -672,7 +673,7 @@ static void vlapic_write(struct vcpu *v,
     case APIC_TDCR:
         vlapic_set_tdcr(vlapic, val & 0xb);
         HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, "timer divisor is 0x%x",
-                    vlapic->timer_divisor);
+                    vlapic->hw.timer_divisor);
         break;
 
     default:
@@ -697,23 +698,23 @@ struct hvm_mmio_handler vlapic_mmio_hand
 
 void vlapic_msr_set(struct vlapic *vlapic, uint64_t value)
 {
-    if ( (vlapic->apic_base_msr ^ value) & MSR_IA32_APICBASE_ENABLE )
+    if ( (vlapic->hw.apic_base_msr ^ value) & MSR_IA32_APICBASE_ENABLE )
     {
         if ( value & MSR_IA32_APICBASE_ENABLE )
         {
             vlapic_reset(vlapic);
-            vlapic->disabled &= ~VLAPIC_HW_DISABLED;
+            vlapic->hw.disabled &= ~VLAPIC_HW_DISABLED;
         }
         else
         {
-            vlapic->disabled |= VLAPIC_HW_DISABLED;
-        }
-    }
-
-    vlapic->apic_base_msr = value;
+            vlapic->hw.disabled |= VLAPIC_HW_DISABLED;
+        }
+    }
+
+    vlapic->hw.apic_base_msr = value;
 
     HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
-                "apic base msr is 0x%016"PRIx64".", vlapic->apic_base_msr);
+                "apic base msr is 0x%016"PRIx64".", vlapic->hw.apic_base_msr);
 }
 
 int vlapic_accept_pic_intr(struct vcpu *v)
@@ -754,7 +755,7 @@ int cpu_get_apic_interrupt(struct vcpu *
     if ( vector == -1 )
         return -1;
  
-    vlapic_set_vector(vector, vlapic->regs + APIC_ISR);
+    vlapic_set_vector(vector, &vlapic->regs->data[APIC_ISR]);
     vlapic_clear_irr(vector, vlapic);
 
     *mode = APIC_DM_FIXED;
@@ -790,7 +791,7 @@ static int vlapic_reset(struct vlapic *v
         vlapic_set_reg(vlapic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED);
 
     vlapic_set_reg(vlapic, APIC_SPIV, 0xff);
-    vlapic->disabled |= VLAPIC_SW_DISABLED;
+    vlapic->hw.disabled |= VLAPIC_SW_DISABLED;
 
     return 1;
 }
@@ -799,10 +800,9 @@ static void lapic_info(struct vlapic *s)
 static void lapic_info(struct vlapic *s)
 {
     printk("*****lapic state:*****\n");
-    printk("lapic 0x%"PRIx64".\n", s->apic_base_msr);
-    printk("lapic 0x%x.\n", s->disabled);
-    printk("lapic 0x%x.\n", s->timer_divisor);
-    printk("lapic 0x%x.\n", s->timer_pending_count);
+    printk("lapic 0x%"PRIx64".\n", s->hw.apic_base_msr);
+    printk("lapic 0x%x.\n", s->hw.disabled);
+    printk("lapic 0x%x.\n", s->hw.timer_divisor);
 }
 #else
 static void lapic_info(struct vlapic *s)
@@ -816,15 +816,8 @@ static void lapic_save(hvm_domain_contex
 
     lapic_info(s);
 
-    hvm_put_64u(h, s->apic_base_msr);
-    hvm_put_32u(h, s->disabled);
-    hvm_put_32u(h, s->timer_divisor);
-
-    /*XXX: need this?*/
-    hvm_put_32u(h, s->timer_pending_count);
-
-    hvm_put_buffer(h, (char*)s->regs, 0x3f0);
-
+    hvm_put_struct(h, &s->hw);
+    hvm_put_struct(h, s->regs);
 }
 
 static int lapic_load(hvm_domain_context_t *h, void *opaque, int version_id)
@@ -836,19 +829,13 @@ static int lapic_load(hvm_domain_context
     if (version_id != 1)
         return -EINVAL;
 
-    s->apic_base_msr = hvm_get_64u(h);
-    s->disabled = hvm_get_32u(h);
-    s->timer_divisor = hvm_get_32u(h);
-
-    /*XXX: need this?*/
-    s->timer_pending_count = hvm_get_32u(h);
-
-    hvm_get_buffer(h, (char*)s->regs, 0x3f0);
+    hvm_get_struct(h, &s->hw);
+    hvm_get_struct(h, s->regs);
 
     /* rearm the actiemr if needed */
     tmict = vlapic_get_reg(s, APIC_TMICT);
     if (tmict > 0) {
-        uint64_t period = APIC_BUS_CYCLE_NS * (uint32_t)tmict * 
s->timer_divisor;
+        uint64_t period = APIC_BUS_CYCLE_NS * (uint32_t)tmict * 
s->hw.timer_divisor;
 
         create_periodic_time(v, &s->pt, period, s->pt.irq,
                              vlapic_lvtt_period(s), NULL, s);
@@ -887,9 +874,9 @@ int vlapic_init(struct vcpu *v)
     hvm_register_savevm(v->domain, "xen_hvm_lapic", v->vcpu_id, 1, lapic_save, 
lapic_load, vlapic);
     vlapic_reset(vlapic);
 
-    vlapic->apic_base_msr = MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
+    vlapic->hw.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->hw.apic_base_msr |= MSR_IA32_APICBASE_BSP;
 
     init_timer(&vlapic->pt.timer, pt_timer_fn, &vlapic->pt, v->processor);
 
diff -r dccdc3ee0efc -r 2457741f4ec3 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Sat Jan 20 11:17:39 2007 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Sat Jan 20 11:17:40 2007 +0000
@@ -2309,7 +2309,7 @@ static inline int vmx_do_msr_read(struct
         msr_content = __vmread(GUEST_SYSENTER_EIP);
         break;
     case MSR_IA32_APICBASE:
-        msr_content = vcpu_vlapic(v)->apic_base_msr;
+        msr_content = vcpu_vlapic(v)->hw.apic_base_msr;
         break;
     default:
         if ( long_mode_do_msr_read(regs) )
diff -r dccdc3ee0efc -r 2457741f4ec3 xen/arch/x86/hvm/vpic.c
--- a/xen/arch/x86/hvm/vpic.c   Sat Jan 20 11:17:39 2007 +0000
+++ b/xen/arch/x86/hvm/vpic.c   Sat Jan 20 11:17:40 2007 +0000
@@ -35,9 +35,9 @@
 #include <asm/hvm/support.h>
 
 #define vpic_domain(v) (container_of((v), struct domain, \
-                        arch.hvm_domain.irq.vpic[!vpic->is_master]))
-#define __vpic_lock(v) &container_of((v), struct hvm_irq, \
-                                     vpic[!(v)->is_master])->lock
+                        arch.hvm_domain.vpic[!vpic->is_master]))
+#define __vpic_lock(v) &container_of((v), struct hvm_domain, \
+                                        vpic[!(v)->is_master])->irq_lock
 #define vpic_lock(v)   spin_lock(__vpic_lock(v))
 #define vpic_unlock(v) spin_unlock(__vpic_lock(v))
 #define vpic_is_locked(v) spin_is_locked(__vpic_lock(v))
@@ -45,7 +45,7 @@
 
 /* Return the highest priority found in mask. Return 8 if none. */
 #define VPIC_PRIO_NONE 8
-static int vpic_get_priority(struct vpic *vpic, uint8_t mask)
+static int vpic_get_priority(struct hvm_hw_vpic *vpic, uint8_t mask)
 {
     int prio;
 
@@ -61,7 +61,7 @@ static int vpic_get_priority(struct vpic
 }
 
 /* Return the PIC's highest priority pending interrupt. Return -1 if none. */
-static int vpic_get_highest_priority_irq(struct vpic *vpic)
+static int vpic_get_highest_priority_irq(struct hvm_hw_vpic *vpic)
 {
     int cur_priority, priority, irq;
     uint8_t mask;
@@ -92,7 +92,7 @@ static int vpic_get_highest_priority_irq
     return (priority < cur_priority) ? irq : -1;
 }
 
-static void vpic_update_int_output(struct vpic *vpic)
+static void vpic_update_int_output(struct hvm_hw_vpic *vpic)
 {
     int irq;
 
@@ -129,7 +129,7 @@ static void vpic_update_int_output(struc
     }
 }
 
-static void __vpic_intack(struct vpic *vpic, int irq)
+static void __vpic_intack(struct hvm_hw_vpic *vpic, int irq)
 {
     uint8_t mask = 1 << irq;
 
@@ -147,7 +147,7 @@ static void __vpic_intack(struct vpic *v
     vpic_update_int_output(vpic);
 }
 
-static int vpic_intack(struct vpic *vpic)
+static int vpic_intack(struct hvm_hw_vpic *vpic)
 {
     int irq = -1;
 
@@ -174,7 +174,7 @@ static int vpic_intack(struct vpic *vpic
     return irq;
 }
 
-static void vpic_ioport_write(struct vpic *vpic, uint32_t addr, uint32_t val)
+static void vpic_ioport_write(struct hvm_hw_vpic *vpic, uint32_t addr, 
uint32_t val)
 {
     int priority, cmd, irq;
     uint8_t mask;
@@ -291,7 +291,7 @@ static void vpic_ioport_write(struct vpi
     vpic_unlock(vpic);
 }
 
-static uint32_t vpic_ioport_read(struct vpic *vpic, uint32_t addr)
+static uint32_t vpic_ioport_read(struct hvm_hw_vpic *vpic, uint32_t addr)
 {
     if ( vpic->poll )
     {
@@ -307,7 +307,7 @@ static uint32_t vpic_ioport_read(struct 
 
 static int vpic_intercept_pic_io(ioreq_t *p)
 {
-    struct vpic *vpic;
+    struct hvm_hw_vpic *vpic;
     uint32_t data;
 
     if ( (p->size != 1) || (p->count != 1) )
@@ -316,7 +316,7 @@ static int vpic_intercept_pic_io(ioreq_t
         return 1;
     }
 
-    vpic = &current->domain->arch.hvm_domain.irq.vpic[p->addr >> 7];
+    vpic = &current->domain->arch.hvm_domain.vpic[p->addr >> 7];
 
     if ( p->dir == IOREQ_WRITE )
     {
@@ -340,7 +340,7 @@ static int vpic_intercept_pic_io(ioreq_t
 
 static int vpic_intercept_elcr_io(ioreq_t *p)
 {
-    struct vpic *vpic;
+    struct hvm_hw_vpic *vpic;
     uint32_t data;
 
     if ( (p->size != 1) || (p->count != 1) )
@@ -349,7 +349,7 @@ static int vpic_intercept_elcr_io(ioreq_
         return 1;
     }
 
-    vpic = &current->domain->arch.hvm_domain.irq.vpic[p->addr & 1];
+    vpic = &current->domain->arch.hvm_domain.vpic[p->addr & 1];
 
     if ( p->dir == IOREQ_WRITE )
     {
@@ -379,7 +379,7 @@ static int vpic_intercept_elcr_io(ioreq_
 }
 
 #ifdef HVM_DEBUG_SUSPEND
-static void vpic_info(struct vpic *s)
+static void vpic_info(struct hvm_hw_vpic *s)
 {
     printk("*****pic state:*****\n");
     printk("pic 0x%x.\n", s->irr);
@@ -399,61 +399,27 @@ static void vpic_info(struct vpic *s)
     printk("pic 0x%x.\n", s->is_master);
 }
 #else
-static void vpic_info(struct vpic *s)
+static void vpic_info(struct hvm_hw_vpic *s)
 {
 }
 #endif
 
 static void vpic_save(hvm_domain_context_t *h, void *opaque)
 {
-    struct vpic *s = opaque;
+    struct hvm_hw_vpic *s = opaque;
     
     vpic_info(s);
-
-    hvm_put_8u(h, s->irr);
-    hvm_put_8u(h, s->imr);
-    hvm_put_8u(h, s->isr);
-    hvm_put_8u(h, s->irq_base);
-    hvm_put_8u(h, s->init_state);
-    hvm_put_8u(h, s->priority_add);
-    hvm_put_8u(h, s->readsel_isr);
-
-    hvm_put_8u(h, s->poll);
-    hvm_put_8u(h, s->auto_eoi);
-
-    hvm_put_8u(h, s->rotate_on_auto_eoi);
-    hvm_put_8u(h, s->special_fully_nested_mode);
-    hvm_put_8u(h, s->special_mask_mode);
-
-    hvm_put_8u(h, s->elcr);
-    hvm_put_8u(h, s->int_output);
+    hvm_put_struct(h, s);
 }
 
 static int vpic_load(hvm_domain_context_t *h, void *opaque, int version_id)
 {
-    struct vpic *s = opaque;
+    struct hvm_hw_vpic *s = opaque;
     
     if (version_id != 1)
         return -EINVAL;
 
-    s->irr = hvm_get_8u(h);
-    s->imr = hvm_get_8u(h);
-    s->isr = hvm_get_8u(h);
-    s->irq_base = hvm_get_8u(h);
-    s->init_state = hvm_get_8u(h);
-    s->priority_add = hvm_get_8u(h);
-    s->readsel_isr = hvm_get_8u(h);
-
-    s->poll = hvm_get_8u(h);
-    s->auto_eoi = hvm_get_8u(h);
-
-    s->rotate_on_auto_eoi = hvm_get_8u(h);
-    s->special_fully_nested_mode = hvm_get_8u(h);
-    s->special_mask_mode = hvm_get_8u(h);
-
-    s->elcr = hvm_get_8u(h);
-    s->int_output = hvm_get_8u(h);
-
+    hvm_get_struct(h, s);
     vpic_info(s);
 
     return 0;
@@ -461,10 +427,10 @@ static int vpic_load(hvm_domain_context_
 
 void vpic_init(struct domain *d)
 {
-    struct vpic *vpic;
+    struct hvm_hw_vpic *vpic;
 
     /* Master PIC. */
-    vpic = &d->arch.hvm_domain.irq.vpic[0];
+    vpic = &d->arch.hvm_domain.vpic[0];
     memset(vpic, 0, sizeof(*vpic));
     vpic->is_master = 1;
     vpic->elcr      = 1 << 2;
@@ -482,7 +448,7 @@ void vpic_init(struct domain *d)
 
 void vpic_irq_positive_edge(struct domain *d, int irq)
 {
-    struct vpic *vpic = &d->arch.hvm_domain.irq.vpic[irq >> 3];
+    struct hvm_hw_vpic *vpic = &d->arch.hvm_domain.vpic[irq >> 3];
     uint8_t mask = 1 << (irq & 7);
 
     ASSERT(irq <= 15);
@@ -498,7 +464,7 @@ void vpic_irq_positive_edge(struct domai
 
 void vpic_irq_negative_edge(struct domain *d, int irq)
 {
-    struct vpic *vpic = &d->arch.hvm_domain.irq.vpic[irq >> 3];
+    struct hvm_hw_vpic *vpic = &d->arch.hvm_domain.vpic[irq >> 3];
     uint8_t mask = 1 << (irq & 7);
 
     ASSERT(irq <= 15);
@@ -515,7 +481,7 @@ int cpu_get_pic_interrupt(struct vcpu *v
 int cpu_get_pic_interrupt(struct vcpu *v, int *type)
 {
     int irq, vector;
-    struct vpic *vpic = &v->domain->arch.hvm_domain.irq.vpic[0];
+    struct hvm_hw_vpic *vpic = &v->domain->arch.hvm_domain.vpic[0];
 
     if ( !vlapic_accept_pic_intr(v) || !vpic->int_output )
         return -1;
diff -r dccdc3ee0efc -r 2457741f4ec3 xen/include/asm-x86/hvm/domain.h
--- a/xen/include/asm-x86/hvm/domain.h  Sat Jan 20 11:17:39 2007 +0000
+++ b/xen/include/asm-x86/hvm/domain.h  Sat Jan 20 11:17:40 2007 +0000
@@ -26,6 +26,7 @@
 #include <asm/hvm/vlapic.h>
 #include <asm/hvm/io.h>
 #include <public/hvm/params.h>
+#include <public/hvm/save.h>
 
 typedef void SaveStateHandler(hvm_domain_context_t *h, void *opaque);
 typedef int LoadStateHandler(hvm_domain_context_t *h, void *opaque, int 
version_id);
@@ -50,7 +51,11 @@ struct hvm_domain {
 
     struct hvm_io_handler  io_handler;
 
-    struct hvm_irq         irq;
+    /* Lock protects access to irq, vpic and vioapic. */
+    spinlock_t             irq_lock;
+    struct hvm_hw_irq      irq;
+    struct hvm_hw_vpic     vpic[2]; /* 0=master; 1=slave */
+    struct hvm_hw_vioapic  vioapic;
 
     /* hvm_print_line() logging. */
     char                   pbuf[80];
diff -r dccdc3ee0efc -r 2457741f4ec3 xen/include/asm-x86/hvm/irq.h
--- a/xen/include/asm-x86/hvm/irq.h     Sat Jan 20 11:17:39 2007 +0000
+++ b/xen/include/asm-x86/hvm/irq.h     Sat Jan 20 11:17:40 2007 +0000
@@ -26,70 +26,7 @@
 #include <xen/spinlock.h>
 #include <asm/hvm/vpic.h>
 #include <asm/hvm/vioapic.h>
-
-struct hvm_irq {
-    /* Lock protects access to all other fields. */
-    spinlock_t lock;
-
-    /*
-     * Virtual interrupt wires for a single PCI bus.
-     * Indexed by: device*4 + INTx#.
-     */
-    DECLARE_BITMAP(pci_intx, 32*4);
-
-    /*
-     * Virtual interrupt wires for ISA devices.
-     * Indexed by ISA IRQ (assumes no ISA-device IRQ sharing).
-     */
-    DECLARE_BITMAP(isa_irq, 16);
-
-    /* Virtual interrupt and via-link for paravirtual platform driver. */
-    unsigned int callback_via_asserted;
-    enum {
-        HVMIRQ_callback_none,
-        HVMIRQ_callback_gsi,
-        HVMIRQ_callback_pci_intx
-    } callback_via_type;
-    union {
-        unsigned int gsi;
-        struct { uint8_t dev, intx; } pci;
-    } callback_via;
-
-    /*
-     * PCI-ISA interrupt router.
-     * Each PCI <device:INTx#> is 'wire-ORed' into one of four links using
-     * the traditional 'barber's pole' mapping ((device + INTx#) & 3).
-     * The router provides a programmable mapping from each link to a GSI.
-     */
-    u8 pci_link_route[4];
-
-    /* Number of INTx wires asserting each PCI-ISA link. */
-    u8 pci_link_assert_count[4];
-
-    /*
-     * Number of wires asserting each GSI.
-     * 
-     * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space
-     * except ISA IRQ 0, which is connected to GSI 2.
-     * PCI links map into this space via the PCI-ISA bridge.
-     * 
-     * GSIs 16+ are used only be PCI devices. The mapping from PCI device to
-     * GSI is as follows: ((device*4 + device/8 + INTx#) & 31) + 16
-     */
-    u8 gsi_assert_count[VIOAPIC_NUM_PINS];
-
-    /*
-     * GSIs map onto PIC/IO-APIC in the usual way:
-     *  0-7:  Master 8259 PIC, IO-APIC pins 0-7
-     *  8-15: Slave  8259 PIC, IO-APIC pins 8-15
-     *  16+ : IO-APIC pins 16+
-     */
-    struct vpic    vpic[2]; /* 0=master; 1=slave */
-    struct vioapic vioapic;
-
-    /* Last VCPU that was delivered a LowestPrio interrupt. */
-    u8 round_robin_prev_vcpu;
-};
+#include <public/hvm/save.h>
 
 #define hvm_pci_intx_gsi(dev, intx)  \
     (((((dev)<<2) + ((dev)>>3) + (intx)) & 31) + 16)
diff -r dccdc3ee0efc -r 2457741f4ec3 xen/include/asm-x86/hvm/vioapic.h
--- a/xen/include/asm-x86/hvm/vioapic.h Sat Jan 20 11:17:39 2007 +0000
+++ b/xen/include/asm-x86/hvm/vioapic.h Sat Jan 20 11:17:40 2007 +0000
@@ -28,13 +28,7 @@
 #include <xen/config.h>
 #include <xen/types.h>
 #include <xen/smp.h>
-
-#ifdef __ia64__
-#define VIOAPIC_IS_IOSAPIC 1
-#define VIOAPIC_NUM_PINS  24
-#else
-#define VIOAPIC_NUM_PINS  48 /* 16 ISA IRQs, 32 non-legacy PCI IRQS. */
-#endif
+#include <public/hvm/save.h>
 
 #if !VIOAPIC_IS_IOSAPIC
 #define VIOAPIC_VERSION_ID 0x11 /* IOAPIC version */
@@ -58,38 +52,9 @@
 #define VIOAPIC_REG_VERSION 0x01
 #define VIOAPIC_REG_ARB_ID  0x02 /* x86 IOAPIC only */
 
-#define domain_vioapic(d) (&(d)->arch.hvm_domain.irq.vioapic)
+#define domain_vioapic(d) (&(d)->arch.hvm_domain.vioapic)
 #define vioapic_domain(v) (container_of((v), struct domain, \
-                                        arch.hvm_domain.irq.vioapic))
-
-union vioapic_redir_entry
-{
-    uint64_t bits;
-    struct {
-        uint8_t vector;
-        uint8_t delivery_mode:3;
-        uint8_t dest_mode:1;
-        uint8_t delivery_status:1;
-        uint8_t polarity:1;
-        uint8_t remote_irr:1;
-        uint8_t trig_mode:1;
-        uint8_t mask:1;
-        uint8_t reserve:7;
-#if !VIOAPIC_IS_IOSAPIC
-        uint8_t reserved[4];
-        uint8_t dest_id;
-#else
-        uint8_t reserved[3];
-        uint16_t dest_id;
-#endif
-    } fields;
-};
-
-struct vioapic {
-    uint32_t ioregsel, id;
-    unsigned long base_address;
-    union vioapic_redir_entry redirtbl[VIOAPIC_NUM_PINS];
-};
+                                        arch.hvm_domain.vioapic))
 
 void vioapic_init(struct domain *d);
 void vioapic_irq_positive_edge(struct domain *d, unsigned int irq);
diff -r dccdc3ee0efc -r 2457741f4ec3 xen/include/asm-x86/hvm/vlapic.h
--- a/xen/include/asm-x86/hvm/vlapic.h  Sat Jan 20 11:17:39 2007 +0000
+++ b/xen/include/asm-x86/hvm/vlapic.h  Sat Jan 20 11:17:40 2007 +0000
@@ -44,31 +44,28 @@
  */
 #define VLAPIC_HW_DISABLED              0x1
 #define VLAPIC_SW_DISABLED              0x2
-#define vlapic_sw_disabled(vlapic)  ((vlapic)->disabled & VLAPIC_SW_DISABLED)
-#define vlapic_hw_disabled(vlapic)  ((vlapic)->disabled & VLAPIC_HW_DISABLED)
-#define vlapic_disabled(vlapic)     ((vlapic)->disabled)
-#define vlapic_enabled(vlapic)      (!vlapic_disabled(vlapic))
+#define vlapic_sw_disabled(vlapic) ((vlapic)->hw.disabled & VLAPIC_SW_DISABLED)
+#define vlapic_hw_disabled(vlapic) ((vlapic)->hw.disabled & VLAPIC_HW_DISABLED)
+#define vlapic_disabled(vlapic)    ((vlapic)->hw.disabled)
+#define vlapic_enabled(vlapic)     (!vlapic_disabled(vlapic))
 
 struct vlapic {
-    uint64_t             apic_base_msr;
-    uint32_t             disabled; /* VLAPIC_xx_DISABLED */
-    uint32_t             timer_divisor;
-    struct periodic_time pt;
-    int                  timer_pending_count;
-    s_time_t             timer_last_update;
-    struct page_info     *regs_page;
-    void                 *regs;
+    struct hvm_hw_lapic      hw;
+    struct hvm_hw_lapic_regs *regs;
+    struct periodic_time     pt;
+    s_time_t                 timer_last_update;
+    struct page_info         *regs_page;
 };
 
 static inline uint32_t vlapic_get_reg(struct vlapic *vlapic, uint32_t reg)
 {
-    return *((uint32_t *)(vlapic->regs + reg));
+    return *((uint32_t *)(&vlapic->regs->data[reg]));
 }
 
 static inline void vlapic_set_reg(
     struct vlapic *vlapic, uint32_t reg, uint32_t val)
 {
-    *((uint32_t *)(vlapic->regs + reg)) = val;
+    *((uint32_t *)(&vlapic->regs->data[reg])) = val;
 }
 
 int vlapic_set_irq(struct vlapic *vlapic, uint8_t vec, uint8_t trig);
diff -r dccdc3ee0efc -r 2457741f4ec3 xen/include/asm-x86/hvm/vpic.h
--- a/xen/include/asm-x86/hvm/vpic.h    Sat Jan 20 11:17:39 2007 +0000
+++ b/xen/include/asm-x86/hvm/vpic.h    Sat Jan 20 11:17:40 2007 +0000
@@ -27,51 +27,7 @@
 #ifndef __ASM_X86_HVM_VPIC_H__
 #define __ASM_X86_HVM_VPIC_H__
 
-struct vpic {
-    /* IR line bitmasks. */
-    uint8_t irr, imr, isr;
-
-    /* Line IRx maps to IRQ irq_base+x */
-    uint8_t irq_base;
-
-    /*
-     * Where are we in ICW2-4 initialisation (0 means no init in progress)?
-     * Bits 0-1 (=x): Next write at A=1 sets ICW(x+1).
-     * Bit 2: ICW1.IC4  (1 == ICW4 included in init sequence)
-     * Bit 3: ICW1.SNGL (0 == ICW3 included in init sequence)
-     */
-    uint8_t init_state:4;
-
-    /* IR line with highest priority. */
-    uint8_t priority_add:4;
-
-    /* Reads from A=0 obtain ISR or IRR? */
-    uint8_t readsel_isr:1;
-
-    /* Reads perform a polling read? */
-    uint8_t poll:1;
-
-    /* Automatically clear IRQs from the ISR during INTA? */
-    uint8_t auto_eoi:1;
-
-    /* Automatically rotate IRQ priorities during AEOI? */
-    uint8_t rotate_on_auto_eoi:1;
-
-    /* Exclude slave inputs when considering in-service IRQs? */
-    uint8_t special_fully_nested_mode:1;
-
-    /* Special mask mode excludes masked IRs from AEOI and priority checks. */
-    uint8_t special_mask_mode:1;
-
-    /* Is this a master PIC or slave PIC? (NB. This is not programmable.) */
-    uint8_t is_master:1;
-
-    /* Edge/trigger selection. */
-    uint8_t elcr;
-
-    /* Virtual INT output. */
-    uint8_t int_output;
-};
+#include <public/hvm/save.h>
 
 void vpic_irq_positive_edge(struct domain *d, int irq);
 void vpic_irq_negative_edge(struct domain *d, int irq);
diff -r dccdc3ee0efc -r 2457741f4ec3 xen/include/public/hvm/save.h
--- a/xen/include/public/hvm/save.h     Sat Jan 20 11:17:39 2007 +0000
+++ b/xen/include/public/hvm/save.h     Sat Jan 20 11:17:40 2007 +0000
@@ -83,7 +83,6 @@ struct hvm_hw_cpu {
     uint64_t ldtr_base;
     uint64_t idtr_base;
     uint64_t gdtr_base;
-
 
     uint32_t cs_arbytes;
     uint32_t ds_arbytes;
@@ -137,5 +136,182 @@ struct hvm_hw_pit {
 };
 
 
+/*
+ * PIC
+ */
+#define HVM_SAVE_TYPE_PIC 3
+struct hvm_hw_vpic {
+    /* IR line bitmasks. */
+    uint8_t irr;
+    uint8_t imr;
+    uint8_t isr;
+
+    /* Line IRx maps to IRQ irq_base+x */
+    uint8_t irq_base;
+
+    /*
+     * Where are we in ICW2-4 initialisation (0 means no init in progress)?
+     * Bits 0-1 (=x): Next write at A=1 sets ICW(x+1).
+     * Bit 2: ICW1.IC4  (1 == ICW4 included in init sequence)
+     * Bit 3: ICW1.SNGL (0 == ICW3 included in init sequence)
+     */
+    uint8_t init_state:4;
+
+    /* IR line with highest priority. */
+    uint8_t priority_add:4;
+
+    /* Reads from A=0 obtain ISR or IRR? */
+    uint8_t readsel_isr:1;
+
+    /* Reads perform a polling read? */
+    uint8_t poll:1;
+
+    /* Automatically clear IRQs from the ISR during INTA? */
+    uint8_t auto_eoi:1;
+
+    /* Automatically rotate IRQ priorities during AEOI? */
+    uint8_t rotate_on_auto_eoi:1;
+
+    /* Exclude slave inputs when considering in-service IRQs? */
+    uint8_t special_fully_nested_mode:1;
+
+    /* Special mask mode excludes masked IRs from AEOI and priority checks. */
+    uint8_t special_mask_mode:1;
+
+    /* Is this a master PIC or slave PIC? (NB. This is not programmable.) */
+    uint8_t is_master:1;
+
+    /* Edge/trigger selection. */
+    uint8_t elcr;
+
+    /* Virtual INT output. */
+    uint8_t int_output;
+};
+
+
+/*
+ * IO-APIC
+ */
+#define HVM_SAVE_TYPE_IOAPIC 4
+
+#ifdef __ia64__
+#define VIOAPIC_IS_IOSAPIC 1
+#define VIOAPIC_NUM_PINS  24
+#else
+#define VIOAPIC_NUM_PINS  48 /* 16 ISA IRQs, 32 non-legacy PCI IRQS. */
+#endif
+
+struct hvm_hw_vioapic {
+    uint64_t base_address;
+    uint32_t ioregsel;
+    uint32_t id;
+    union vioapic_redir_entry
+    {
+        uint64_t bits;
+        struct {
+            uint8_t vector;
+            uint8_t delivery_mode:3;
+            uint8_t dest_mode:1;
+            uint8_t delivery_status:1;
+            uint8_t polarity:1;
+            uint8_t remote_irr:1;
+            uint8_t trig_mode:1;
+            uint8_t mask:1;
+            uint8_t reserve:7;
+#if !VIOAPIC_IS_IOSAPIC
+            uint8_t reserved[4];
+            uint8_t dest_id;
+#else
+            uint8_t reserved[3];
+            uint16_t dest_id;
+#endif
+        } fields;
+    } redirtbl[VIOAPIC_NUM_PINS];
+};
+
+
+/*
+ * IRQ
+ */
+#define HVM_SAVE_TYPE_IRQ 5
+struct hvm_hw_irq {
+    /*
+     * Virtual interrupt wires for a single PCI bus.
+     * Indexed by: device*4 + INTx#.
+     */
+    DECLARE_BITMAP(pci_intx, 32*4);
+
+    /*
+     * Virtual interrupt wires for ISA devices.
+     * Indexed by ISA IRQ (assumes no ISA-device IRQ sharing).
+     */
+    DECLARE_BITMAP(isa_irq, 16);
+
+    /* Virtual interrupt and via-link for paravirtual platform driver. */
+    uint32_t callback_via_asserted;
+    union {
+        enum {
+            HVMIRQ_callback_none,
+            HVMIRQ_callback_gsi,
+            HVMIRQ_callback_pci_intx
+        } callback_via_type;
+        uint32_t pad; /* So the next field will be aligned */
+    };
+    union {
+        uint32_t gsi;
+        struct { uint8_t dev, intx; } pci;
+    } callback_via;
+
+    /*
+     * PCI-ISA interrupt router.
+     * Each PCI <device:INTx#> is 'wire-ORed' into one of four links using
+     * the traditional 'barber's pole' mapping ((device + INTx#) & 3).
+     * The router provides a programmable mapping from each link to a GSI.
+     */
+    u8 pci_link_route[4];
+
+    /* Number of INTx wires asserting each PCI-ISA link. */
+    u8 pci_link_assert_count[4];
+
+    /*
+     * Number of wires asserting each GSI.
+     * 
+     * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space
+     * except ISA IRQ 0, which is connected to GSI 2.
+     * PCI links map into this space via the PCI-ISA bridge.
+     * 
+     * GSIs 16+ are used only be PCI devices. The mapping from PCI device to
+     * GSI is as follows: ((device*4 + device/8 + INTx#) & 31) + 16
+     */
+    u8 gsi_assert_count[VIOAPIC_NUM_PINS];
+
+    /*
+     * GSIs map onto PIC/IO-APIC in the usual way:
+     *  0-7:  Master 8259 PIC, IO-APIC pins 0-7
+     *  8-15: Slave  8259 PIC, IO-APIC pins 8-15
+     *  16+ : IO-APIC pins 16+
+     */
+
+    /* Last VCPU that was delivered a LowestPrio interrupt. */
+    u8 round_robin_prev_vcpu;
+};
+
+
+/*
+ * LAPIC
+ */
+#define HVM_SAVE_TYPE_LAPIC 6
+struct hvm_hw_lapic {
+    uint64_t             apic_base_msr;
+    uint32_t             disabled; /* VLAPIC_xx_DISABLED */
+    uint32_t             timer_divisor;
+};
+
+#define HVM_SAVE_TYPE_LAPIC_REGS 7
+
+struct hvm_hw_lapic_regs {
+    /* A 4k page of register state */
+    uint8_t  data[0x400];
+};
 
 #endif /* __XEN_PUBLIC_HVM_SAVE_H__ */

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