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 01: PIT

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [HVM] Save/restore cleanups 01: PIT
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sat, 20 Jan 2007 09:10:13 -0800
Delivery-date: Sat, 20 Jan 2007 09:10:59 -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 1169291858 0
# Node ID 56228886421d877623cdd27e68d6e5b6d1592946
# Parent  dcb145f858e32a1d310a5558d4e12bb0521a625d
[HVM] Save/restore cleanups 01: PIT
Define public structure for the saved PIT data and use it instead
of a series of explicit loads and stores.
Don't save ephemeral Xen timer structs; rebuild them instead.
Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
---
 xen/arch/x86/domain.c             |    7 -
 xen/arch/x86/hvm/hvm.c            |    1 
 xen/arch/x86/hvm/i8254.c          |  255 ++++++++++++++------------------------
 xen/arch/x86/hvm/intercept.c      |    2 
 xen/arch/x86/hvm/vioapic.c        |    2 
 xen/include/asm-x86/hvm/support.h |    7 -
 xen/include/asm-x86/hvm/vpt.h     |   26 ---
 xen/include/public/hvm/save.h     |  138 ++++++++++++++++++++
 8 files changed, 255 insertions(+), 183 deletions(-)

diff -r dcb145f858e3 -r 56228886421d xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Fri Jan 19 15:23:41 2007 +0000
+++ b/xen/arch/x86/domain.c     Sat Jan 20 11:17:38 2007 +0000
@@ -329,9 +329,6 @@ int vcpu_initialise(struct vcpu *v)
 
     pae_l3_cache_init(&v->arch.pae_l3_cache);
 
-    /* This should move to arch_domain_create(). */
-    if ( !is_idle_domain(d) && (v->vcpu_id == 0) )
-        pit_init(v, cpu_khz);
 
     if ( is_hvm_domain(d) )
     {
@@ -340,6 +337,10 @@ int vcpu_initialise(struct vcpu *v)
     }
     else
     {
+        /* PV guests get an emulated PIT too for video BIOSes to use. */
+        if ( !is_idle_domain(d) && (v->vcpu_id == 0) )
+            pit_init(v, cpu_khz);
+
         v->arch.schedule_tail = continue_nonidle_domain;
         v->arch.ctxt_switch_from = paravirt_ctxt_switch_from;
         v->arch.ctxt_switch_to   = paravirt_ctxt_switch_to;
diff -r dcb145f858e3 -r 56228886421d xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Fri Jan 19 15:23:41 2007 +0000
+++ b/xen/arch/x86/hvm/hvm.c    Sat Jan 20 11:17:38 2007 +0000
@@ -194,6 +194,7 @@ int hvm_vcpu_initialise(struct vcpu *v)
     if ( v->vcpu_id != 0 )
         return 0;
 
+    pit_init(v, cpu_khz);
     rtc_init(v, RTC_PORT(0), RTC_IRQ);
     pmtimer_init(v, ACPI_PM_TMR_BLK_ADDRESS);
     hpet_init(v);
diff -r dcb145f858e3 -r 56228886421d xen/arch/x86/hvm/i8254.c
--- a/xen/arch/x86/hvm/i8254.c  Fri Jan 19 15:23:41 2007 +0000
+++ b/xen/arch/x86/hvm/i8254.c  Sat Jan 20 11:17:38 2007 +0000
@@ -76,37 +76,42 @@ uint64_t muldiv64(uint64_t a, uint32_t b
     return res.ll;
 }
 
-static int pit_get_count(PITChannelState *s)
+static int pit_get_count(PITState *s, int channel)
 {
     uint64_t d;
     int  counter;
-
-    d = muldiv64(hvm_get_guest_time(s->pt.vcpu) - s->count_load_time, 
PIT_FREQ, ticks_per_sec(s->pt.vcpu));
-    switch(s->mode) {
+    struct hvm_hw_pit_channel *c = &s->hw.channels[channel];
+    struct periodic_time *pt = &s->pt[channel];
+
+    d = muldiv64(hvm_get_guest_time(pt->vcpu) 
+                 - c->count_load_time, PIT_FREQ, ticks_per_sec(pt->vcpu));
+    switch(c->mode) {
     case 0:
     case 1:
     case 4:
     case 5:
-        counter = (s->count - d) & 0xffff;
+        counter = (c->count - d) & 0xffff;
         break;
     case 3:
         /* XXX: may be incorrect for odd counts */
-        counter = s->count - ((2 * d) % s->count);
+        counter = c->count - ((2 * d) % c->count);
         break;
     default:
-        counter = s->count - (d % s->count);
+        counter = c->count - (d % c->count);
         break;
     }
     return counter;
 }
 
 /* get pit output bit */
-static int pit_get_out1(PITChannelState *s, int64_t current_time)
-{
+int pit_get_out(PITState *pit, int channel, int64_t current_time)
+{
+    struct hvm_hw_pit_channel *s = &pit->hw.channels[channel];
     uint64_t d;
     int out;
 
-    d = muldiv64(current_time - s->count_load_time, PIT_FREQ, 
ticks_per_sec(s->pt.vcpu));
+    d = muldiv64(current_time - s->count_load_time, 
+                 PIT_FREQ, ticks_per_sec(pit->pt[channel].vcpu));
     switch(s->mode) {
     default:
     case 0:
@@ -132,16 +137,11 @@ static int pit_get_out1(PITChannelState 
     return out;
 }
 
-int pit_get_out(PITState *pit, int channel, int64_t current_time)
-{
-    PITChannelState *s = &pit->channels[channel];
-    return pit_get_out1(s, current_time);
-}
-
 /* val must be 0 or 1 */
 void pit_set_gate(PITState *pit, int channel, int val)
 {
-    PITChannelState *s = &pit->channels[channel];
+    struct hvm_hw_pit_channel *s = &pit->hw.channels[channel];
+    struct periodic_time *pt = &pit->pt[channel];
 
     switch(s->mode) {
     default:
@@ -153,7 +153,7 @@ void pit_set_gate(PITState *pit, int cha
     case 5:
         if (s->gate < val) {
             /* restart counting on rising edge */
-            s->count_load_time = hvm_get_guest_time(s->pt.vcpu);
+            s->count_load_time = hvm_get_guest_time(pt->vcpu);
 //            pit_irq_timer_update(s, s->count_load_time);
         }
         break;
@@ -161,7 +161,7 @@ void pit_set_gate(PITState *pit, int cha
     case 3:
         if (s->gate < val) {
             /* restart counting on rising edge */
-            s->count_load_time = hvm_get_guest_time(s->pt.vcpu);
+            s->count_load_time = hvm_get_guest_time(pt->vcpu);
 //            pit_irq_timer_update(s, s->count_load_time);
         }
         /* XXX: disable/enable counting */
@@ -172,23 +172,25 @@ void pit_set_gate(PITState *pit, int cha
 
 int pit_get_gate(PITState *pit, int channel)
 {
-    PITChannelState *s = &pit->channels[channel];
-    return s->gate;
+    return pit->hw.channels[channel].gate;
 }
 
 void pit_time_fired(struct vcpu *v, void *priv)
 {
-    PITChannelState *s = priv;
+    struct hvm_hw_pit_channel *s = priv;
     s->count_load_time = hvm_get_guest_time(v);
 }
 
-static inline void pit_load_count(PITChannelState *s, int channel, int val)
+static inline void pit_load_count(PITState *pit, int channel, int val)
 {
     u32 period;
+    struct hvm_hw_pit_channel *s = &pit->hw.channels[channel];
+    struct periodic_time *pt = &pit->pt[channel];
+    struct vcpu *v;
 
     if (val == 0)
         val = 0x10000;
-    s->count_load_time = hvm_get_guest_time(s->pt.vcpu);
+    s->count_load_time = hvm_get_guest_time(pt->vcpu);
     s->count = val;
     period = DIV_ROUND((val * 1000000000ULL), PIT_FREQ);
 
@@ -204,30 +206,38 @@ static inline void pit_load_count(PITCha
             (long long)s->count_load_time);
 #endif
 
+    /* Choose a vcpu to set the timer on: current if appropriate else vcpu 0 */
+    if ( likely(pit == &current->domain->arch.hvm_domain.pl_time.vpit) )
+        v = current;
+    else 
+        v = container_of(pit, struct domain, 
+                         arch.hvm_domain.pl_time.vpit)->vcpu[0];
+
     switch (s->mode) {
         case 2:
             /* create periodic time */
-            create_periodic_time(current, &s->pt, period, 0, 0, 
pit_time_fired, s);
+            create_periodic_time(v, pt, period, 0, 0, pit_time_fired, s);
             break;
         case 1:
             /* create one shot time */
-            create_periodic_time(current, &s->pt, period, 0, 1, 
pit_time_fired, s);
+            create_periodic_time(v, pt, period, 0, 1, pit_time_fired, s);
 #ifdef DEBUG_PIT
             printk("HVM_PIT: create one shot time.\n");
 #endif
             break;
         default:
-            destroy_periodic_time(&s->pt);
+            destroy_periodic_time(pt);
             break;
     }
 }
 
 /* if already latched, do not latch again */
-static void pit_latch_count(PITChannelState *s)
-{
-    if (!s->count_latched) {
-        s->latched_count = pit_get_count(s);
-        s->count_latched = s->rw_mode;
+static void pit_latch_count(PITState *s, int channel)
+{
+    struct hvm_hw_pit_channel *c = &s->hw.channels[channel];
+    if (!c->count_latched) {
+        c->latched_count = pit_get_count(s, channel);
+        c->count_latched = c->rw_mode;
     }
 }
 
@@ -235,7 +245,7 @@ static void pit_ioport_write(void *opaqu
 {
     PITState *pit = opaque;
     int channel, access;
-    PITChannelState *s;
+    struct hvm_hw_pit_channel *s;
     val &= 0xff;
 
     addr &= 3;
@@ -244,15 +254,15 @@ static void pit_ioport_write(void *opaqu
         if (channel == 3) {
             /* read back command */
             for(channel = 0; channel < 3; channel++) {
-                s = &pit->channels[channel];
+                s = &pit->hw.channels[channel];
                 if (val & (2 << channel)) {
                     if (!(val & 0x20)) {
-                        pit_latch_count(s);
+                        pit_latch_count(pit, channel);
                     }
                     if (!(val & 0x10) && !s->status_latched) {
                         /* status latch */
                         /* XXX: add BCD and null count */
-                        s->status =  (pit_get_out1(s, 
hvm_get_guest_time(s->pt.vcpu)) << 7) |
+                        s->status = (pit_get_out(pit, channel, 
hvm_get_guest_time(pit->pt[channel].vcpu)) << 7) |
                             (s->rw_mode << 4) |
                             (s->mode << 1) |
                             s->bcd;
@@ -261,10 +271,10 @@ static void pit_ioport_write(void *opaqu
                 }
             }
         } else {
-            s = &pit->channels[channel];
+            s = &pit->hw.channels[channel];
             access = (val >> 4) & 3;
             if (access == 0) {
-                pit_latch_count(s);
+                pit_latch_count(pit, channel);
             } else {
                 s->rw_mode = access;
                 s->read_state = access;
@@ -276,21 +286,21 @@ static void pit_ioport_write(void *opaqu
             }
         }
     } else {
-        s = &pit->channels[addr];
+        s = &pit->hw.channels[addr];
         switch(s->write_state) {
         default:
         case RW_STATE_LSB:
-            pit_load_count(s, addr, val);
+            pit_load_count(pit, addr, val);
             break;
         case RW_STATE_MSB:
-            pit_load_count(s, addr, val << 8);
+            pit_load_count(pit, addr, val << 8);
             break;
         case RW_STATE_WORD0:
             s->write_latch = val;
             s->write_state = RW_STATE_WORD1;
             break;
         case RW_STATE_WORD1:
-            pit_load_count(s, addr, s->write_latch | (val << 8));
+            pit_load_count(pit, addr, s->write_latch | (val << 8));
             s->write_state = RW_STATE_WORD0;
             break;
         }
@@ -301,10 +311,10 @@ static uint32_t pit_ioport_read(void *op
 {
     PITState *pit = opaque;
     int ret, count;
-    PITChannelState *s;
+    struct hvm_hw_pit_channel *s;
     
     addr &= 3;
-    s = &pit->channels[addr];
+    s = &pit->hw.channels[addr];
     if (s->status_latched) {
         s->status_latched = 0;
         ret = s->status;
@@ -328,20 +338,20 @@ static uint32_t pit_ioport_read(void *op
         switch(s->read_state) {
         default:
         case RW_STATE_LSB:
-            count = pit_get_count(s);
+            count = pit_get_count(pit, addr);
             ret = count & 0xff;
             break;
         case RW_STATE_MSB:
-            count = pit_get_count(s);
+            count = pit_get_count(pit, addr);
             ret = (count >> 8) & 0xff;
             break;
         case RW_STATE_WORD0:
-            count = pit_get_count(s);
+            count = pit_get_count(pit, addr);
             ret = count & 0xff;
             s->read_state = RW_STATE_WORD1;
             break;
         case RW_STATE_WORD1:
-            count = pit_get_count(s);
+            count = pit_get_count(pit, addr);
             ret = (count >> 8) & 0xff;
             s->read_state = RW_STATE_WORD0;
             break;
@@ -352,19 +362,19 @@ static uint32_t pit_ioport_read(void *op
 
 void pit_stop_channel0_irq(PITState * pit)
 {
-    PITChannelState *s = &pit->channels[0];
-    destroy_periodic_time(&s->pt);
+    destroy_periodic_time(&pit->pt[0]);
 }
 
 #ifdef HVM_DEBUG_SUSPEND
 static void pit_info(PITState *pit)
 {
-    PITChannelState *s;
+    struct hvm_hw_pit_channel *s;
+    struct periodic_time *pt;
     int i;
 
     for(i = 0; i < 3; i++) {
         printk("*****pit channel %d's state:*****\n", i);
-        s = &pit->channels[i];
+        s = &pit->hw.channels[i];
         printk("pit 0x%x.\n", s->count);
         printk("pit 0x%x.\n", s->latched_count);
         printk("pit 0x%x.\n", s->count_latched);
@@ -379,8 +389,8 @@ static void pit_info(PITState *pit)
         printk("pit 0x%x.\n", s->gate);
         printk("pit %"PRId64"\n", s->count_load_time);
 
-        if (s->pt) {
-            struct periodic_time *pt = s->pt;
+        pt = &pit->pt[i];
+        if (pt) {
             printk("pit channel %d has a periodic timer:\n", i);
             printk("pt %d.\n", pt->enabled);
             printk("pt %d.\n", pt->one_shot);
@@ -405,131 +415,64 @@ static void pit_save(hvm_domain_context_
 {
     struct domain *d = opaque;
     PITState *pit = &d->arch.hvm_domain.pl_time.vpit;
-    PITChannelState *s;
-    struct periodic_time *pt;
-    int i, pti = -1;
     
     pit_info(pit);
 
-    for(i = 0; i < 3; i++) {
-        s = &pit->channels[i];
-        hvm_put_32u(h, s->count);
-        hvm_put_16u(h, s->latched_count);
-        hvm_put_8u(h, s->count_latched);
-        hvm_put_8u(h, s->status_latched);
-        hvm_put_8u(h, s->status);
-        hvm_put_8u(h, s->read_state);
-        hvm_put_8u(h, s->write_state);
-        hvm_put_8u(h, s->write_latch);
-        hvm_put_8u(h, s->rw_mode);
-        hvm_put_8u(h, s->mode);
-        hvm_put_8u(h, s->bcd);
-        hvm_put_8u(h, s->gate);
-        hvm_put_64u(h, s->count_load_time);
-
-        if (s->pt.enabled && pti == -1)
-            pti = i;
-    }
-
-    pt = &pit->channels[pti].pt;
-
-    /* save the vcpu for pt */
-    hvm_put_32u(h, pt->vcpu->vcpu_id);
-
-    /* save guest time */
-    hvm_put_8u(h, pti);
-    hvm_put_32u(h, pt->pending_intr_nr);
-    hvm_put_64u(h, pt->last_plt_gtime);
-
+    /* Save the PIT hardware state */
+    hvm_put_struct(h, &pit->hw);
 }
 
 static int pit_load(hvm_domain_context_t *h, void *opaque, int version_id)
 {
     struct domain *d = opaque;
     PITState *pit = &d->arch.hvm_domain.pl_time.vpit;
-    PITChannelState *s;
-    int i, pti, vcpu_id;
-    u32 period;
+    int i;
 
     if (version_id != 1)
         return -EINVAL;
 
+    /* Restore the PIT hardware state */
+    hvm_get_struct(h, &pit->hw);
+    
+    /* Recreate platform timers from hardware state.  There will be some 
+     * time jitter here, but the wall-clock will have jumped massively, so 
+     * we hope the guest can handle it. */
+
     for(i = 0; i < 3; i++) {
-        s = &pit->channels[i];
-        s->count = hvm_get_32u(h);
-        s->latched_count = hvm_get_16u(h);
-        s->count_latched = hvm_get_8u(h);
-        s->status_latched = hvm_get_8u(h);
-        s->status = hvm_get_8u(h);
-        s->read_state = hvm_get_8u(h);
-        s->write_state = hvm_get_8u(h);
-        s->write_latch = hvm_get_8u(h);
-        s->rw_mode = hvm_get_8u(h);
-        s->mode = hvm_get_8u(h);
-        s->bcd = hvm_get_8u(h);
-        s->gate = hvm_get_8u(h);
-        s->count_load_time = hvm_get_64u(h);
-    }
-
-    vcpu_id = hvm_get_32u(h);
-
-    pti = hvm_get_8u(h);
-    if ( pti < 0 || pti > 2) {
-        printk("pit load get a wrong channel %d when HVM resume.\n", pti);
-        return -EINVAL;
-    }
-
-    s = &pit->channels[pti];
-    period = DIV_ROUND((s->count * 1000000000ULL), PIT_FREQ);
-
-    printk("recreate periodic timer %d in mode %d, freq=%d.\n", pti, s->mode, 
period);
-    switch (s->mode) {
-        case 2:
-            /* create periodic time */
-            create_periodic_time(d->vcpu[vcpu_id], &s->pt, period, 0, 0, 
pit_time_fired, s);
-            break;
-        case 1:
-            /* create one shot time */
-            create_periodic_time(d->vcpu[vcpu_id], &s->pt, period, 0, 1, 
pit_time_fired, s);
-            break;
-        default:
-            printk("pit mode %"PRId8" should not use periodic timer!\n", 
s->mode);
-            return -EINVAL;
-    }
-    s->pt.pending_intr_nr = hvm_get_32u(h);
-    s->pt.last_plt_gtime = hvm_get_64u(h);
+        pit_load_count(pit, i, pit_get_count(pit, i));
+        pit->pt[i].last_plt_gtime = hvm_get_guest_time(d->vcpu[0]);
+    }
 
     pit_info(pit);
-
     return 0;
 }
 
 static void pit_reset(void *opaque)
 {
     PITState *pit = opaque;
-    PITChannelState *s;
+    struct hvm_hw_pit_channel *s;
     int i;
 
     for(i = 0;i < 3; i++) {
-        s = &pit->channels[i];
-        destroy_periodic_time(&s->pt);
+        s = &pit->hw.channels[i];
+        destroy_periodic_time(&pit->pt[i]);
         s->mode = 0xff; /* the init mode */
         s->gate = (i != 2);
-        pit_load_count(s, i, 0);
+        pit_load_count(pit, i, 0);
     }
 }
 
 void pit_init(struct vcpu *v, unsigned long cpu_khz)
 {
     PITState *pit = &v->domain->arch.hvm_domain.pl_time.vpit;
-    PITChannelState *s;
-
-    s = &pit->channels[0];
-    s->pt.vcpu = v;
+    struct periodic_time *pt;
+
+    pt = &pit->pt[0];  
+    pt->vcpu = v;
     /* the timer 0 is connected to an IRQ */
-    init_timer(&s->pt.timer, pt_timer_fn, &s->pt, v->processor);
-    s++; s->pt.vcpu = v;
-    s++; s->pt.vcpu = v;
+    init_timer(&pt->timer, pt_timer_fn, pt, v->processor);
+    pt++; pt->vcpu = v;
+    pt++; pt->vcpu = v;
 
     hvm_register_savevm(v->domain, "xen_hvm_i8254", PIT_BASE, 1, pit_save, 
pit_load, v->domain);
     register_portio_handler(v->domain, PIT_BASE, 4, handle_pit_io);
@@ -546,20 +489,18 @@ void pit_migrate_timers(struct vcpu *v)
 void pit_migrate_timers(struct vcpu *v)
 {
     PITState *pit = &v->domain->arch.hvm_domain.pl_time.vpit;
-    PITChannelState *s;
-
-    s = &pit->channels[0];
-    if ( s->pt.vcpu == v && s->pt.enabled )
-        migrate_timer(&s->pt.timer, v->processor);
+    struct periodic_time *pt;
+
+    pt = &pit->pt[0];
+    if ( pt->vcpu == v && pt->enabled )
+        migrate_timer(&pt->timer, v->processor);
 }
 
 void pit_deinit(struct domain *d)
 {
     PITState *pit = &d->arch.hvm_domain.pl_time.vpit;
-    PITChannelState *s;
-
-    s = &pit->channels[0];
-    kill_timer(&s->pt.timer);
+
+    kill_timer(&pit->pt[0].timer);
 }
 
 /* the intercept action for PIT DM retval:0--not handled; 1--handled */  
@@ -590,7 +531,7 @@ static void speaker_ioport_write(void *o
 static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 {
     PITState *pit = opaque;
-    pit->speaker_data_on = (val >> 1) & 1;
+    pit->hw.speaker_data_on = (val >> 1) & 1;
     pit_set_gate(pit, 2, val & 1);
 }
 
@@ -598,10 +539,10 @@ static uint32_t speaker_ioport_read(void
 {
     PITState *pit = opaque;
     int out = pit_get_out(pit, 2,
-                          hvm_get_guest_time(pit->channels[2].pt.vcpu));
+                          hvm_get_guest_time(pit->pt[2].vcpu));
     /* Refresh clock toggles at about 15us. We approximate as 2^14ns. */
     unsigned int refresh_clock = ((unsigned int)NOW() >> 14) & 1;
-    return ((pit->speaker_data_on << 1) | pit_get_gate(pit, 2) |
+    return ((pit->hw.speaker_data_on << 1) | pit_get_gate(pit, 2) |
             (out << 5) | refresh_clock << 4);
 }
 
diff -r dcb145f858e3 -r 56228886421d xen/arch/x86/hvm/intercept.c
--- a/xen/arch/x86/hvm/intercept.c      Fri Jan 19 15:23:41 2007 +0000
+++ b/xen/arch/x86/hvm/intercept.c      Sat Jan 20 11:17:38 2007 +0000
@@ -358,6 +358,8 @@ int hvm_load(struct vcpu *v, hvm_domain_
         instance_id = hvm_get_32u(h);
         version_id = hvm_get_32u(h);
 
+        printk("HVM S/R Loading \"%s\" instance %#x\n", idstr, instance_id);
+
         rec_len = hvm_get_32u(h);
         rec_pos = hvm_ctxt_tell(h);
 
diff -r dcb145f858e3 -r 56228886421d xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c        Fri Jan 19 15:23:41 2007 +0000
+++ b/xen/arch/x86/hvm/vioapic.c        Sat Jan 20 11:17:38 2007 +0000
@@ -312,7 +312,7 @@ static inline int pit_channel0_enabled(v
 static inline int pit_channel0_enabled(void)
 {
     PITState *pit = &current->domain->arch.hvm_domain.pl_time.vpit;
-    struct periodic_time *pt = &pit->channels[0].pt;
+    struct periodic_time *pt = &pit->pt[0];
     return pt->enabled;
 }
 
diff -r dcb145f858e3 -r 56228886421d xen/include/asm-x86/hvm/support.h
--- a/xen/include/asm-x86/hvm/support.h Fri Jan 19 15:23:41 2007 +0000
+++ b/xen/include/asm-x86/hvm/support.h Sat Jan 20 11:17:38 2007 +0000
@@ -186,7 +186,6 @@ static inline void hvm_put_buffer(hvm_do
     h->cur += len;
 }
 
-
 static inline char hvm_get_byte(hvm_domain_context_t *h)
 {
     if (h->cur >= HVM_CTXT_SIZE) {
@@ -239,6 +238,12 @@ static inline void hvm_get_buffer(hvm_do
     memcpy(buf, &h->data[h->cur], len);
     h->cur += len;
 }
+
+#define hvm_put_struct(_h, _p) \
+    hvm_put_buffer((_h), (char *)(_p), sizeof(*(_p)))
+#define hvm_get_struct(_h, _p) \
+    hvm_get_buffer((_h), (char *)(_p), sizeof(*(_p)))
+
 
 extern int hvm_save(struct vcpu*, hvm_domain_context_t *h);
 extern int hvm_load(struct vcpu*, hvm_domain_context_t *h);
diff -r dcb145f858e3 -r 56228886421d xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h     Fri Jan 19 15:23:41 2007 +0000
+++ b/xen/include/asm-x86/hvm/vpt.h     Sat Jan 20 11:17:38 2007 +0000
@@ -29,7 +29,7 @@
 #include <xen/timer.h>
 #include <xen/list.h>
 #include <asm/hvm/vpic.h>
-
+#include <public/hvm/save.h>
 
 #define HPET_TIMER_NUM     3    /* 3 timers supported now */
 struct HPET {
@@ -90,27 +90,11 @@ struct periodic_time {
 #define PIT_FREQ 1193181
 #define PIT_BASE 0x40
 
-typedef struct PITChannelState {
-    int count; /* can be 65536 */
-    u16 latched_count;
-    u8 count_latched;
-    u8 status_latched;
-    u8 status;
-    u8 read_state;
-    u8 write_state;
-    u8 write_latch;
-    u8 rw_mode;
-    u8 mode;
-    u8 bcd; /* not supported */
-    u8 gate; /* timer start */
-    s64 count_load_time;
+typedef struct PITState {
+    /* Hardware state */
+    struct hvm_hw_pit hw;
     /* irq handling */
-    struct periodic_time pt;
-} PITChannelState;
-
-typedef struct PITState {
-    PITChannelState channels[3];
-    int speaker_data_on;
+    struct periodic_time pt[3];
 } PITState;
 
 #define RTC_SIZE 14
diff -r dcb145f858e3 -r 56228886421d xen/include/public/hvm/save.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/public/hvm/save.h     Sat Jan 20 11:17:38 2007 +0000
@@ -0,0 +1,138 @@
+/* 
+ * hvm/save.h
+ *
+ * Structure definitions for HVM state that is held by Xen and must
+ * be saved along with the domain's memory and device-model state.
+ *
+ * 
+ * Copyright (c) 2007 XenSource Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __XEN_PUBLIC_HVM_SAVE_H__
+#define __XEN_PUBLIC_HVM_SAVE_H__
+
+/*
+ * Structures in this header *must* have the same layout in 32bit 
+ * and 64bit environments: this means that all fields must be explicitly 
+ * sized types and aligned to their sizes.
+ *
+ * Only the state necessary for saving and restoring (i.e. fields 
+ * that are analogous to actual hardware state) should go in this file. 
+ * Internal mechanisms should be kept in Xen-private headers.
+ */
+
+
+
+/*
+ * Processor
+ */
+#define HVM_SAVE_TYPE_CPU  1
+struct hvm_hw_cpu {
+    uint64_t eip;
+    uint64_t esp;
+    uint64_t eflags;
+    uint64_t cr0;
+    uint64_t cr3;
+    uint64_t cr4;
+
+    uint32_t cs_sel;
+    uint32_t ds_sel;
+    uint32_t es_sel;
+    uint32_t fs_sel;
+    uint32_t gs_sel;
+    uint32_t ss_sel;
+    uint32_t tr_sel;
+    uint32_t ldtr_sel;
+
+    uint32_t cs_limit;
+    uint32_t ds_limit;
+    uint32_t es_limit;
+    uint32_t fs_limit;
+    uint32_t gs_limit;
+    uint32_t ss_limit;
+    uint32_t tr_limit;
+    uint32_t ldtr_limit;
+    uint32_t idtr_limit;
+    uint32_t gdtr_limit;
+
+    uint64_t cs_base;
+    uint64_t ds_base;
+    uint64_t es_base;
+    uint64_t fs_base;
+    uint64_t gs_base;
+    uint64_t ss_base;
+    uint64_t tr_base;
+    uint64_t ldtr_base;
+    uint64_t idtr_base;
+    uint64_t gdtr_base;
+
+
+    uint32_t cs_arbytes;
+    uint32_t ds_arbytes;
+    uint32_t es_arbytes;
+    uint32_t fs_arbytes;
+    uint32_t gs_arbytes;
+    uint32_t ss_arbytes;
+    uint32_t tr_arbytes;
+    uint32_t ldtr_arbytes;
+
+    uint32_t sysenter_cs;
+    uint32_t padding0;
+
+    uint64_t sysenter_esp;
+    uint64_t sysenter_eip;
+
+    /* msr for em64t */
+    uint64_t shadow_gs;
+    uint64_t flags;
+
+    /* same size as VMX_MSR_COUNT */
+    uint64_t msr_items[6];
+    uint64_t vmxassist_enabled;
+};
+
+
+/* 
+ *  PIT
+ */
+#define HVM_SAVE_TYPE_PIT 2
+struct hvm_hw_pit {
+    struct hvm_hw_pit_channel {
+        int64_t count_load_time;
+        uint32_t count; /* can be 65536 */
+        uint16_t latched_count;
+        uint8_t count_latched;
+        uint8_t status_latched;
+        uint8_t status;
+        uint8_t read_state;
+        uint8_t write_state;
+        uint8_t write_latch;
+        uint8_t rw_mode;
+        uint8_t mode;
+        uint8_t bcd; /* not supported */
+        uint8_t gate; /* timer start */
+    } channels[3];  /* 3 x 24 bytes */
+    uint32_t speaker_data_on;
+};
+
+
+
+#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 01: PIT, Xen patchbot-unstable <=