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] Save/restore cleanups 03: IRQ

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [HVM] Save/restore cleanups 03: IRQ
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sat, 20 Jan 2007 09:10:15 -0800
Delivery-date: Sat, 20 Jan 2007 09:10:28 -0800
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 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [HVM] Save/restore cleanups 03: IRQ, Xen patchbot-unstable <=